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; }
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); }
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)); }
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); }
// [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; }
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; }
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); }
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); } }
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); } }
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; }
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; }
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; }