Пример #1
0
END_DEFAULTS

bool AArtiTeleport::Use (bool pickup)
{
	fixed_t destX;
	fixed_t destY;
	angle_t destAngle;

	if (deathmatch)
	{
		unsigned int selections = deathmatchstarts.Size ();
		unsigned int i = pr_tele() % selections;
		destX = deathmatchstarts[i].x << FRACBITS;
		destY = deathmatchstarts[i].y << FRACBITS;
		destAngle = ANG45 * (deathmatchstarts[i].angle/45);
	}
	else
	{
		destX = playerstarts[Owner->player - players].x << FRACBITS;
		destY = playerstarts[Owner->player - players].y << FRACBITS;
		destAngle = ANG45 * (playerstarts[Owner->player - players].angle/45);
	}
	P_Teleport (Owner, destX, destY, ONFLOORZ, destAngle, true, true, false);
	if (gameinfo.gametype == GAME_Hexen && Owner->player->morphTics)
	{ // Teleporting away will undo any morph effects (pig)
		P_UndoPlayerMorph (Owner->player);
	}
	if (gameinfo.gametype == GAME_Heretic)
	{ // Full volume laugh
		S_Sound (Owner, CHAN_VOICE, "*evillaugh", 1, ATTN_NONE);
	}
	return true;
}
Пример #2
0
void P_TeleportToPlayerStarts (AActor *victim)
{
	DVector3 dest;

	FPlayerStart *start = G_PickPlayerStart(0, PPS_FORCERANDOM | PPS_NOBLOCKINGCHECK);
	dest = start->pos;
	dest.Z = ONFLOORZ;
	P_Teleport (victim, dest, (double)start->angle, TELF_SOURCEFOG | TELF_DESTFOG);
}
Пример #3
0
DEFINE_ACTION_FUNCTION(AActor, Teleport)
{
	PARAM_SELF_PROLOGUE(AActor);
	PARAM_FLOAT(x);
	PARAM_FLOAT(y);
	PARAM_FLOAT(z);
	PARAM_ANGLE(an);
	PARAM_INT(flags);
	ACTION_RETURN_BOOL(P_Teleport(self, DVector3(x, y, z), an, flags));
}
Пример #4
0
void P_TeleportToPlayerStarts (AActor *victim)
{
	fixed_t destX,destY;
	angle_t destAngle;

	FPlayerStart *start = G_PickPlayerStart(0, PPS_FORCERANDOM | PPS_NOBLOCKINGCHECK);
	destX = start->x;
	destY = start->y;
	destAngle = ANG45 * (start->angle/45);
	P_Teleport (victim, destX, destY, ONFLOORZ, destAngle, true, true, false);
}
Пример #5
0
// [RH] Teleport a group of actors centered around source_tid so
// that they become centered around dest_tid instead.
bool EV_TeleportGroup (int group_tid, AActor *victim, int source_tid, int dest_tid, bool moveSource, bool fog)
{
	AActor *sourceOrigin, *destOrigin;
	{
		FActorIterator iterator (source_tid);
		sourceOrigin = iterator.Next ();
	}
	if (sourceOrigin == NULL)
	{ // If there is no source origin, behave like TeleportOther
		return EV_TeleportOther (group_tid, dest_tid, fog);
	}

	{
		NActorIterator iterator (NAME_TeleportDest, dest_tid);
		destOrigin = iterator.Next ();
	}
	if (destOrigin == NULL)
	{
		return false;
	}

	bool didSomething = false;
	bool floorz = !destOrigin->IsKindOf (PClass::FindClass("TeleportDest2"));

	// Use the passed victim if group_tid is 0
	if (group_tid == 0 && victim != NULL)
	{
		didSomething = DoGroupForOne (victim, sourceOrigin, destOrigin, floorz, fog);
	}
	else
	{
		FActorIterator iterator (group_tid);

		// For each actor with tid matching arg0, move it to the same
		// position relative to destOrigin as it is relative to sourceOrigin
		// before the teleport.
		while ( (victim = iterator.Next ()) )
		{
			didSomething |= DoGroupForOne (victim, sourceOrigin, destOrigin, floorz, fog);
		}
	}

	if (moveSource && didSomething)
	{
		didSomething |=
			P_Teleport (sourceOrigin, destOrigin->PosAtZ(floorz ? ONFLOORZ : destOrigin->Z()), 0., TELF_KEEPORIENTATION);
		sourceOrigin->Angles.Yaw = destOrigin->Angles.Yaw;
	}

	return didSomething;
}
Пример #6
0
static bool DoGroupForOne (AActor *victim, AActor *source, AActor *dest, bool floorz, bool fog)
{
	DAngle an = dest->Angles.Yaw - source->Angles.Yaw;
	DVector2 off = victim->Pos() - source->Pos();
	DAngle offAngle = victim->Angles.Yaw - source->Angles.Yaw;
	DVector2 newp = { off.X * an.Cos() - off.Y * an.Sin(), off.X * an.Sin() + off.Y * an.Cos() };
	double z = floorz ? ONFLOORZ : dest->Z() + victim->Z() - source->Z();

	bool res =
		P_Teleport (victim, DVector3(dest->Pos().XY() + newp, z),
							0., fog ? (TELF_DESTFOG | TELF_SOURCEFOG) : TELF_KEEPORIENTATION);
	// P_Teleport only changes angle if fog is true
	victim->Angles.Yaw = (dest->Angles.Yaw + victim->Angles.Yaw - source->Angles.Yaw).Normalized360();

	return res;
}
Пример #7
0
void P_TeleportToPlayerStarts (AActor *victim)
{
	int i,selections=0;
	fixed_t destX,destY;
	angle_t destAngle;

	for (i = 0; i < MAXPLAYERS;i++)
	{
	    if (!playeringame[i]) continue;
		selections++;
	}
	i = pr_telestarts() % selections;
	destX = playerstarts[i].x << FRACBITS;
	destY = playerstarts[i].y << FRACBITS;
	destAngle = ANG45 * (playerstarts[i].angle/45);
	P_Teleport (victim, destX, destY, ONFLOORZ, destAngle, true, true, false);
}
Пример #8
0
void P_TeleportToDeathmatchStarts (AActor *victim)
{
	unsigned int i, selections;
	DVector3 dest;

	selections = deathmatchstarts.Size ();
	if (selections > 0)
	{
		i = pr_teledm() % selections;
		dest = deathmatchstarts[i].pos;
		dest.Z = ONFLOORZ;
		P_Teleport (victim, dest, (double)deathmatchstarts[i].angle, TELF_SOURCEFOG | TELF_DESTFOG);
	}
	else
	{
	 	P_TeleportToPlayerStarts (victim);
	}
}
Пример #9
0
void P_TeleportToDeathmatchStarts (AActor *victim)
{
	unsigned int i, selections;
	fixed_t destX,destY;
	angle_t destAngle;

	selections = deathmatchstarts.Size ();
	if (selections > 0)
	{
		i = pr_teledm() % selections;
		destX = deathmatchstarts[i].x;
		destY = deathmatchstarts[i].y;
		destAngle = ANG45 * (deathmatchstarts[i].angle/45);
		P_Teleport (victim, destX, destY, ONFLOORZ, destAngle, true, true, false);
	}
	else
	{
	 	P_TeleportToPlayerStarts (victim);
	}
}
Пример #10
0
bool AArtiTeleport::Use (bool pickup)
{
	fixed_t destX;
	fixed_t destY;
	angle_t destAngle;

	if (deathmatch)
	{
		unsigned int selections = deathmatchstarts.Size ();
		unsigned int i = pr_tele() % selections;
		destX = deathmatchstarts[i].x;
		destY = deathmatchstarts[i].y;
		destAngle = ANG45 * (deathmatchstarts[i].angle/45);
	}
	else
	{
		destX = playerstarts[Owner->player - players].x;
		destY = playerstarts[Owner->player - players].y;
		destAngle = ANG45 * (playerstarts[Owner->player - players].angle/45);
	}
	P_Teleport (Owner, destX, destY, ONFLOORZ, destAngle, true, true, false);
	bool canlaugh = true;
 	if (Owner->player->morphTics && (Owner->player->MorphStyle & MORPH_UNDOBYCHAOSDEVICE))
 	{ // Teleporting away will undo any morph effects (pig)
		if (!P_UndoPlayerMorph (Owner->player, Owner->player, MORPH_UNDOBYCHAOSDEVICE)
			&& (Owner->player->MorphStyle & MORPH_FAILNOLAUGH))
		{
			canlaugh = false;
		}
 	}
	if (canlaugh)
 	{ // Full volume laugh
 		S_Sound (Owner, CHAN_VOICE, "*evillaugh", 1, ATTN_NONE);
 	}
	return true;
}
Пример #11
0
bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, int flags)
{
	AActor *searcher;
	double z;
	DAngle angle = 0.;
	double s = 0, c = 0;
	double vx = 0, vy = 0;
	DAngle badangle = 0.;

	if (thing == NULL)
	{ // Teleport function called with an invalid actor
		return false;
	}
	bool predicting = (thing->player && (thing->player->cheats & CF_PREDICTING));
	if (thing->flags2 & MF2_NOTELEPORT)
	{
		return false;
	}
	if (side != 0)
	{ // Don't teleport if hit back of line, so you can get out of teleporter.
		return 0;
	}
	searcher = SelectTeleDest(tid, tag, predicting);
	if (searcher == NULL)
	{
		return false;
	}
	// [RH] Lee Killough's changes for silent teleporters from BOOM
	if ((flags & (TELF_ROTATEBOOM|TELF_ROTATEBOOMINVERSE)) && line)
	{
		// Get the angle between the exit thing and source linedef.
		// Rotate 90 degrees, so that walking perpendicularly across
		// teleporter linedef causes thing to exit in the direction
		// indicated by the exit thing.
		angle = line->Delta().Angle() - searcher->Angles.Yaw + 90.;
		if (flags & TELF_ROTATEBOOMINVERSE) angle = -angle;

		// Sine, cosine of angle adjustment
		s = angle.Sin();
		c = angle.Cos();

		// Velocity of thing crossing teleporter linedef
		vx = thing->Vel.X;
		vy = thing->Vel.Y;

		z = searcher->Z();
	}
	else if (searcher->IsKindOf (PClass::FindClass(NAME_TeleportDest2)))
	{
		z = searcher->Z();
	}
	else
	{
		z = ONFLOORZ;
	}
	if ((i_compatflags2 & COMPATF2_BADANGLES) && (thing->player != NULL))
	{
		badangle = 0.01;
	}
	if (P_Teleport (thing, DVector3(searcher->Pos(), z), searcher->Angles.Yaw + badangle, flags))
	{
		// [RH] Lee Killough's changes for silent teleporters from BOOM
		if (line)
		{
			if (flags & (TELF_ROTATEBOOM| TELF_ROTATEBOOMINVERSE))
			{
				// Rotate thing according to difference in angles (or not - Boom got the direction wrong here.)
				thing->Angles.Yaw += angle;

				// Rotate thing's velocity to come out of exit just like it entered
				thing->Vel.X = vx*c - vy*s;
				thing->Vel.Y = vy*c + vx*s;
			}
		}
		if (vx == 0 && vy == 0 && thing->player != NULL && thing->player->mo == thing && !predicting)
		{
			thing->player->mo->PlayIdle ();
		}
		return true;
	}
	return false;
}
Пример #12
0
bool AArtiTeleport::Use (bool pickup)
{
	fixed_t destX;
	fixed_t destY;
	angle_t destAngle;

	// [BC] Let the server decide where we go.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		return ( true );
	}

	// [BB] If this is a team game and there are valid team starts for the team
	// the owner is on, teleport to one of the team starts.
	const ULONG ownerTeam = Owner->player ? Owner->player->ulTeam : teams.Size( );
	if ( ( GAMEMODE_GetFlags( GAMEMODE_GetCurrentMode( )) & GMF_PLAYERSONTEAMS )
	     && TEAM_CheckIfValid ( ownerTeam )
	     && ( teams[ownerTeam].TeamStarts.Size( ) > 0 ) )
	{
		unsigned int selections = teams[ownerTeam].TeamStarts.Size ();
		unsigned int i = pr_tele() % selections;
		destX = teams[ownerTeam].TeamStarts[i].x;
		destY = teams[ownerTeam].TeamStarts[i].y;
		destAngle = ANG45 * (teams[ownerTeam].TeamStarts[i].angle/45);
	}
	else if (deathmatch)
	{
		unsigned int selections = deathmatchstarts.Size ();
		unsigned int i = pr_tele() % selections;
		destX = deathmatchstarts[i].x;
		destY = deathmatchstarts[i].y;
		destAngle = ANG45 * (deathmatchstarts[i].angle/45);
	}
	else
	{
		FMapThing *pSpot = NULL;
		// [BB] If there is a designated start for this player use it.
		if ( playerstarts[Owner->player - players].type != 0 )
			pSpot = &playerstarts[Owner->player - players];
		// [BB] Otherwise we just have to select a start at random from all available player starts.
		else
			pSpot = SelectRandomCooperativeSpot( Owner->player - players );

		if ( pSpot != NULL )
		{
			destX = pSpot->x;
			destY = pSpot->y;
			destAngle = ANG45 * (pSpot->angle/45);
		}
		else
			I_Error( "ArtiTeleport: No player start found!" );
	}
	P_Teleport (Owner, destX, destY, ONFLOORZ, destAngle, true, true, false);
	bool canlaugh = true;
 	if (Owner->player->morphTics && (Owner->player->MorphStyle & MORPH_UNDOBYCHAOSDEVICE))
 	{ // Teleporting away will undo any morph effects (pig)
		if (!P_UndoPlayerMorph (Owner->player, Owner->player, MORPH_UNDOBYCHAOSDEVICE)
			&& (Owner->player->MorphStyle & MORPH_FAILNOLAUGH))
		{
			canlaugh = false;
		}
 	}
	if (canlaugh)
 	{ // Full volume laugh
 		S_Sound (Owner, CHAN_VOICE, "*evillaugh", 1, ATTN_NONE);

		// [BC] Play the laugh for clients.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
			SERVERCOMMANDS_SoundActor( Owner, CHAN_VOICE, "*evillaugh", 1, ATTN_NONE );
 	}
	return true;
}