void R_ResetAfterTeleport(player_t *player) { #ifndef __LIBRETRO__ R_ResetViewInterpolation(); #endif R_SmoothPlaying_Reset(player); }
bool P_MoveThing(AActor *source, const DVector3 &pos, bool fog) { DVector3 old = source->Pos(); source->SetOrigin (pos, true); if (P_TestMobjLocation (source)) { if (fog) { P_SpawnTeleportFog(source, pos, false, true); P_SpawnTeleportFog(source, old, true, true); } source->ClearInterpolation(); if (source == players[consoleplayer].camera) { R_ResetViewInterpolation(); } return true; } else { source->SetOrigin (old, true); return false; } }
bool P_MoveThing(AActor *source, fixed_t x, fixed_t y, fixed_t z, bool fog) { fixed_t oldx, oldy, oldz; oldx = source->x; oldy = source->y; oldz = source->z; source->SetOrigin (x, y, z); if (P_TestMobjLocation (source)) { if (fog) { Spawn<ATeleportFog> (x, y, z + TELEFOGHEIGHT, ALLOW_REPLACE); Spawn<ATeleportFog> (oldx, oldy, oldz + TELEFOGHEIGHT, ALLOW_REPLACE); } source->PrevX = x; source->PrevY = y; source->PrevZ = z; if (source == players[consoleplayer].camera) { R_ResetViewInterpolation(); } return true; } else { source->SetOrigin (oldx, oldy, oldz); return false; } }
void FGLRenderer::RenderView (player_t* player) { OpenGLFrameBuffer* GLTarget = static_cast<OpenGLFrameBuffer*>(screen); AActor *&LastCamera = GLTarget->LastCamera; checkBenchActive(); if (player->camera != LastCamera) { // If the camera changed don't interpolate // Otherwise there will be some not so nice effects. R_ResetViewInterpolation(); LastCamera=player->camera; } gl_RenderState.SetVertexBuffer(mVBO); GLRenderer->mVBO->Reset(); // reset statistics counters ResetProfilingData(); // Get this before everything else if (cl_capfps || r_NoInterpolate) r_TicFracF = 1.; else r_TicFracF = I_GetTimeFrac (&r_FrameTime); gl_frameMS = I_MSTime(); P_FindParticleSubsectors (); if (!gl.legacyMode) GLRenderer->mLights->Clear(); // NoInterpolateView should have no bearing on camera textures, but needs to be preserved for the main view below. bool saved_niv = NoInterpolateView; NoInterpolateView = false; // prepare all camera textures that have been used in the last frame FCanvasTextureInfo::UpdateAll(); NoInterpolateView = saved_niv; // now render the main view float fovratio; float ratio = WidescreenRatio; if (WidescreenRatio >= 1.3f) { fovratio = 1.333333f; } else { fovratio = ratio; } SetFixedColormap (player); // Check if there's some lights. If not some code can be skipped. TThinkerIterator<ADynamicLight> it(STAT_DLIGHT); GLRenderer->mLightCount = ((it.Next()) != NULL); sector_t * viewsector = RenderViewpoint(player->camera, NULL, FieldOfView.Degrees, ratio, fovratio, true, true); All.Unclock(); }
static void R_SetupFrame (player_t *player) { int cm; boolean NoInterpolate = paused || (menuactive && !demoplayback); viewplayer = player; if (player->mo != oviewer || NoInterpolate) { R_ResetViewInterpolation (); oviewer = player->mo; } tic_vars.frac = I_GetTimeFrac (); if (NoInterpolate) tic_vars.frac = FRACUNIT; R_InterpolateView (player, tic_vars.frac); extralight = player->extralight; viewsin = finesine[viewangle>>ANGLETOFINESHIFT]; viewcos = finecosine[viewangle>>ANGLETOFINESHIFT]; R_DoInterpolations(tic_vars.frac); // killough 3/20/98, 4/4/98: select colormap based on player status if (player->mo->subsector->sector->heightsec != -1) { const sector_t *s = player->mo->subsector->sector->heightsec + sectors; cm = viewz < s->floorheight ? s->bottommap : viewz > s->ceilingheight ? s->topmap : s->midmap; if (cm < 0 || cm > numcolormaps) cm = 0; } else cm = 0; fullcolormap = colormaps[cm]; zlight = c_zlight[cm]; if (player->fixedcolormap) { fixedcolormap = fullcolormap // killough 3/20/98: use fullcolormap + player->fixedcolormap*256*sizeof(lighttable_t); } else fixedcolormap = 0; validcount++; }
void R_InterpolateView(player_t *player) { static mobj_t *oviewer; fixed_t frac; dboolean NoInterpolate = (paused && !walkcamera.type) || (menuactive && !demoplayback); viewplayer = player; if (player->mo != oviewer || NoInterpolate) { R_ResetViewInterpolation(); oviewer = player->mo; } tic_vars.frac = I_GetTimeFrac(); if (NoInterpolate) tic_vars.frac = FRACUNIT; frac = tic_vars.frac; if (movement_smooth) { if (NoInterpolateView) { NoInterpolateView = false; player->prev_viewz = player->viewz; player->prev_viewangle = player->mo->angle + viewangleoffset; player->prev_viewpitch = player->mo->pitch; P_ResetWalkcam(); } if (walkcamera.type != 2) { viewx = player->mo->PrevX + FixedMul (frac, player->mo->x - player->mo->PrevX); viewy = player->mo->PrevY + FixedMul (frac, player->mo->y - player->mo->PrevY); viewz = player->prev_viewz + FixedMul (frac, player->viewz - player->prev_viewz); } else { viewx = walkcamera.PrevX + FixedMul (frac, walkcamera.x - walkcamera.PrevX); viewy = walkcamera.PrevY + FixedMul (frac, walkcamera.y - walkcamera.PrevY); viewz = walkcamera.PrevZ + FixedMul (frac, walkcamera.z - walkcamera.PrevZ); } if (walkcamera.type) { viewangle = walkcamera.PrevAngle + FixedMul (frac, walkcamera.angle - walkcamera.PrevAngle); viewpitch = walkcamera.PrevPitch + FixedMul (frac, walkcamera.pitch - walkcamera.PrevPitch); } else { viewangle = player->prev_viewangle + FixedMul (frac, R_SmoothPlaying_Get(player) + viewangleoffset - player->prev_viewangle); viewpitch = player->prev_viewpitch + FixedMul (frac, player->mo->pitch - player->prev_viewpitch); } } else { if (walkcamera.type != 2) { viewx = player->mo->x; viewy = player->mo->y; viewz = player->viewz; } else { viewx = walkcamera.x; viewy = walkcamera.y; viewz = walkcamera.z; } if (walkcamera.type) { viewangle = walkcamera.angle; viewpitch = walkcamera.pitch; } else { viewangle = R_SmoothPlaying_Get(player); viewpitch = player->mo->pitch; } } if (!paused && movement_smooth) { int i; didInterp = tic_vars.frac != FRACUNIT; if (didInterp) { for (i = numinterpolations - 1; i >= 0; i--) { R_DoAnInterpolation (i, tic_vars.frac); } } } }
// [RH] Modified to support different source and destination ids. // [RH] Modified some more to be accurate. bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBOOL reverse) { int i; line_t *l; if (side || thing->flags2 & MF2_NOTELEPORT || !line || line->sidedef[1] == NULL) return false; FLineIdIterator itr(id); while ((i = itr.Next()) >= 0) { if (line->Index() == i) continue; if ((l=&level.lines[i]) != line && l->backsector) { // Get the thing's position along the source linedef double pos; DVector2 npos; // offsets from line double den; den = line->Delta().LengthSquared(); if (den == 0) { pos = 0; npos.Zero(); } else { double num = (thing->Pos().XY() - line->v1->fPos()) | line->Delta(); if (num <= 0) { pos = 0; } else if (num >= den) { pos = 1; } else { pos = num / den; } npos = thing->Pos().XY() - line->v1->fPos() - line->Delta() * pos; } // Get the angle between the two linedefs, for rotating // orientation and velocity. Rotate 180 degrees, and flip // the position across the exit linedef, if reversed. DAngle angle = l->Delta().Angle() - line->Delta().Angle(); if (!reverse) { angle += 180.; pos = 1 - pos; } // Sine, cosine of angle adjustment double s = angle.Sin(); double c = angle.Cos(); DVector2 p; // Rotate position along normal to match exit linedef p.X = npos.X*c - npos.Y*s; p.Y = npos.Y*c + npos.X*s; // Interpolate position across the exit linedef p += l->v1->fPos() + pos*l->Delta(); // Whether this is a player, and if so, a pointer to its player_t. // Voodoo dolls are excluded by making sure thing->player->mo==thing. player_t *player = thing->player && thing->player->mo == thing ? thing->player : NULL; // Whether walking towards first side of exit linedef steps down bool stepdown = l->frontsector->floorplane.ZatPoint(p) < l->backsector->floorplane.ZatPoint(p); // Height of thing above ground double z = thing->Z() - thing->floorz; // Side to exit the linedef on positionally. // // Notes: // // This flag concerns exit position, not momentum. Due to // roundoff error, the thing can land on either the left or // the right side of the exit linedef, and steps must be // taken to make sure it does not end up on the wrong side. // // Exit momentum is always towards side 1 in a reversed // teleporter, and always towards side 0 otherwise. // // Exiting positionally on side 1 is always safe, as far // as avoiding oscillations and stuck-in-wall problems, // but may not be optimum for non-reversed teleporters. // // Exiting on side 0 can cause oscillations if momentum // is towards side 1, as it is with reversed teleporters. // // Exiting on side 1 slightly improves player viewing // when going down a step on a non-reversed teleporter. // Is this really still necessary with real math instead of imprecise trig tables? #if 1 int side = reverse || (player && stepdown); int fudge = FUDGEFACTOR; double dx = line->Delta().X; double dy = line->Delta().Y; // Make sure we are on correct side of exit linedef. while (P_PointOnLineSidePrecise(p, l) != side && --fudge >= 0) { if (fabs(dx) > fabs(dy)) p.Y -= (dx < 0) != side ? -1 : 1; else p.X += (dy < 0) != side ? -1 : 1; } #endif // Adjust z position to be same height above ground as before. // Ground level at the exit is measured as the higher of the // two floor heights at the exit linedef. z = z + l->sidedef[stepdown]->sector->floorplane.ZatPoint(p); // Attempt to teleport, aborting if blocked if (!P_TeleportMove (thing, DVector3(p, z), false)) { return false; } if (thing == players[consoleplayer].camera) { R_ResetViewInterpolation (); } // Rotate thing's orientation according to difference in linedef angles thing->Angles.Yaw += angle; // Rotate thing's velocity to come out of exit just like it entered p = thing->Vel.XY(); thing->Vel.X = p.X*c - p.Y*s; thing->Vel.Y = p.Y*c + p.X*s; // Adjust a player's view, in case there has been a height change if (player && player->mo == thing) { // Adjust player's local copy of velocity p = player->Vel; player->Vel.X = p.X*c - p.Y*s; player->Vel.Y = p.Y*c + p.X*s; // Save the current deltaviewheight, used in stepping double deltaviewheight = player->deltaviewheight; // Clear deltaviewheight, since we don't want any changes now player->deltaviewheight = 0; // Set player's view according to the newly set parameters P_CalcHeight(player); // Reset the delta to have the same dynamics as before player->deltaviewheight = deltaviewheight; } return true; } } return false; }
void cht_DoCheat (player_t *player, int cheat) { static const char * const BeholdPowers[9] = { "PowerInvulnerable", "PowerStrength", "PowerInvisibility", "PowerIronFeet", "MapRevealer", "PowerLightAmp", "PowerShadow", "PowerMask", "PowerTargeter", }; PClassActor *type; AInventory *item; const char *msg = ""; char msgbuild[32]; int i; switch (cheat) { case CHT_IDDQD: if (!(player->cheats & CF_GODMODE) && player->playerstate == PST_LIVE) { if (player->mo) player->mo->health = deh.GodHealth; player->health = deh.GodHealth; } // fall through to CHT_GOD case CHT_GOD: player->cheats ^= CF_GODMODE; if (player->cheats & CF_GODMODE) msg = GStrings("STSTR_DQDON"); else msg = GStrings("STSTR_DQDOFF"); ST_SetNeedRefresh(); break; case CHT_BUDDHA: player->cheats ^= CF_BUDDHA; if (player->cheats & CF_BUDDHA) msg = GStrings("TXT_BUDDHAON"); else msg = GStrings("TXT_BUDDHAOFF"); break; case CHT_GOD2: player->cheats ^= CF_GODMODE2; if (player->cheats & CF_GODMODE2) msg = GStrings("STSTR_DQD2ON"); else msg = GStrings("STSTR_DQD2OFF"); ST_SetNeedRefresh(); break; case CHT_BUDDHA2: player->cheats ^= CF_BUDDHA2; if (player->cheats & CF_BUDDHA2) msg = GStrings("TXT_BUDDHA2ON"); else msg = GStrings("TXT_BUDDHA2OFF"); break; case CHT_NOCLIP: player->cheats ^= CF_NOCLIP; if (player->cheats & CF_NOCLIP) msg = GStrings("STSTR_NCON"); else msg = GStrings("STSTR_NCOFF"); break; case CHT_NOCLIP2: player->cheats ^= CF_NOCLIP2; if (player->cheats & CF_NOCLIP2) { player->cheats |= CF_NOCLIP; msg = GStrings("STSTR_NC2ON"); } else { player->cheats &= ~CF_NOCLIP; msg = GStrings("STSTR_NCOFF"); } if (player->mo->Vel.X == 0) player->mo->Vel.X = MinVel; // force some lateral movement so that internal variables are up to date break; case CHT_NOVELOCITY: player->cheats ^= CF_NOVELOCITY; if (player->cheats & CF_NOVELOCITY) msg = GStrings("TXT_LEADBOOTSON"); else msg = GStrings("TXT_LEADBOOTSOFF"); break; case CHT_FLY: if (player->mo != NULL) { player->mo->flags7 ^= MF7_FLYCHEAT; if (player->mo->flags7 & MF7_FLYCHEAT) { player->mo->flags |= MF_NOGRAVITY; player->mo->flags2 |= MF2_FLY; msg = GStrings("TXT_LIGHTER"); } else { player->mo->flags &= ~MF_NOGRAVITY; player->mo->flags2 &= ~MF2_FLY; msg = GStrings("TXT_GRAVITY"); } } break; case CHT_MORPH: msg = cht_Morph (player, static_cast<PClassPlayerPawn *>(PClass::FindClass (gameinfo.gametype == GAME_Heretic ? NAME_ChickenPlayer : NAME_PigPlayer)), true); break; case CHT_NOTARGET: player->cheats ^= CF_NOTARGET; if (player->cheats & CF_NOTARGET) msg = "notarget ON"; else msg = "notarget OFF"; break; case CHT_ANUBIS: player->cheats ^= CF_FRIGHTENING; if (player->cheats & CF_FRIGHTENING) msg = "\"Quake with fear!\""; else msg = "No more ogre armor"; break; case CHT_CHASECAM: player->cheats ^= CF_CHASECAM; if (player->cheats & CF_CHASECAM) msg = "chasecam ON"; else msg = "chasecam OFF"; R_ResetViewInterpolation (); break; case CHT_CHAINSAW: if (player->mo != NULL && player->health >= 0) { type = PClass::FindActor("Chainsaw"); if (player->mo->FindInventory (type) == NULL) { player->mo->GiveInventoryType (type); } msg = GStrings("STSTR_CHOPPERS"); } // [RH] The original cheat also set powers[pw_invulnerability] to true. // Since this is a timer and not a boolean, it effectively turned off // the invulnerability powerup, although it looks like it was meant to // turn it on. break; case CHT_POWER: if (player->mo != NULL && player->health >= 0) { item = player->mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2), true); if (item != NULL) { item->Destroy (); msg = GStrings("TXT_CHEATPOWEROFF"); } else { player->mo->GiveInventoryType (RUNTIME_CLASS(APowerWeaponLevel2)); msg = GStrings("TXT_CHEATPOWERON"); } } break; case CHT_IDKFA: cht_Give (player, "backpack"); cht_Give (player, "weapons"); cht_Give (player, "ammo"); cht_Give (player, "keys"); cht_Give (player, "armor"); msg = GStrings("STSTR_KFAADDED"); break; case CHT_IDFA: cht_Give (player, "backpack"); cht_Give (player, "weapons"); cht_Give (player, "ammo"); cht_Give (player, "armor"); msg = GStrings("STSTR_FAADDED"); break; case CHT_BEHOLDV: case CHT_BEHOLDS: case CHT_BEHOLDI: case CHT_BEHOLDR: case CHT_BEHOLDA: case CHT_BEHOLDL: case CHT_PUMPUPI: case CHT_PUMPUPM: case CHT_PUMPUPT: i = cheat - CHT_BEHOLDV; if (i == 4) { level.flags2 ^= LEVEL2_ALLMAP; } else if (player->mo != NULL && player->health >= 0) { item = player->mo->FindInventory(PClass::FindActor(BeholdPowers[i])); if (item == NULL) { if (i != 0) { cht_Give(player, BeholdPowers[i]); if (cheat == CHT_BEHOLDS) { P_GiveBody (player->mo, -100); } } else { // Let's give the item here so that the power doesn't need colormap information. cht_Give(player, "InvulnerabilitySphere"); } } else { item->Destroy (); } } msg = GStrings("STSTR_BEHOLDX"); break; case CHT_MASSACRE: { int killcount = P_Massacre (); // killough 3/22/98: make more intelligent about plural // Ty 03/27/98 - string(s) *not* externalized mysnprintf (msgbuild, countof(msgbuild), "%d Monster%s Killed", killcount, killcount==1 ? "" : "s"); msg = msgbuild; } break; case CHT_HEALTH: if (player->mo != NULL && player->playerstate == PST_LIVE) { player->health = player->mo->health = player->mo->GetDefault()->health; msg = GStrings("TXT_CHEATHEALTH"); } break; case CHT_KEYS: cht_Give (player, "keys"); msg = GStrings("TXT_CHEATKEYS"); break; // [GRB] case CHT_RESSURECT: if (player->playerstate != PST_LIVE && player->mo != nullptr) { if (player->mo->IsKindOf(RUNTIME_CLASS(APlayerChunk))) { Printf("Unable to resurrect. Player is no longer connected to its body.\n"); } else { player->playerstate = PST_LIVE; player->health = player->mo->health = player->mo->GetDefault()->health; player->viewheight = ((APlayerPawn *)player->mo->GetDefault())->ViewHeight; player->mo->flags = player->mo->GetDefault()->flags; player->mo->flags2 = player->mo->GetDefault()->flags2; player->mo->flags3 = player->mo->GetDefault()->flags3; player->mo->flags4 = player->mo->GetDefault()->flags4; player->mo->flags5 = player->mo->GetDefault()->flags5; player->mo->flags6 = player->mo->GetDefault()->flags6; player->mo->flags7 = player->mo->GetDefault()->flags7; player->mo->renderflags &= ~RF_INVISIBLE; player->mo->Height = player->mo->GetDefault()->Height; player->mo->radius = player->mo->GetDefault()->radius; player->mo->special1 = 0; // required for the Hexen fighter's fist attack. // This gets set by AActor::Die as flag for the wimpy death and must be reset here. player->mo->SetState (player->mo->SpawnState); if (!(player->mo->flags2 & MF2_DONTTRANSLATE)) { player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players)); } player->mo->DamageType = NAME_None; if (player->ReadyWeapon != nullptr) { P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetUpState()); } if (player->morphTics > 0) { P_UndoPlayerMorph(player, player); } } } break; case CHT_GIMMIEA: cht_Give (player, "ArtiInvulnerability"); msg = "Valador's Ring of Invunerability"; break; case CHT_GIMMIEB: cht_Give (player, "ArtiInvisibility"); msg = "Shadowsphere"; break; case CHT_GIMMIEC: cht_Give (player, "ArtiHealth"); msg = "Quartz Flask"; break; case CHT_GIMMIED: cht_Give (player, "ArtiSuperHealth"); msg = "Mystic Urn"; break; case CHT_GIMMIEE: cht_Give (player, "ArtiTomeOfPower"); msg = "Tyketto's Tome of Power"; break; case CHT_GIMMIEF: cht_Give (player, "ArtiTorch"); msg = "Torch"; break; case CHT_GIMMIEG: cht_Give (player, "ArtiTimeBomb"); msg = "Delmintalintar's Time Bomb of the Ancients"; break; case CHT_GIMMIEH: cht_Give (player, "ArtiEgg"); msg = "Torpol's Morph Ovum"; break; case CHT_GIMMIEI: cht_Give (player, "ArtiFly"); msg = "Inhilicon's Wings of Wrath"; break; case CHT_GIMMIEJ: cht_Give (player, "ArtiTeleport"); msg = "Darchala's Chaos Device"; break; case CHT_GIMMIEZ: for (int i=0; i<16; i++) { cht_Give (player, "artifacts"); } msg = "All artifacts!"; break; case CHT_TAKEWEAPS: if (player->morphTics || player->mo == NULL || player->mo->health <= 0) { return; } { // Take away all weapons that are either non-wimpy or use ammo. AInventory **invp = &player->mo->Inventory, **lastinvp; for (item = *invp; item != NULL; item = *invp) { lastinvp = invp; invp = &(*invp)->Inventory; if (item->IsKindOf (RUNTIME_CLASS(AWeapon))) { AWeapon *weap = static_cast<AWeapon *> (item); if (!(weap->WeaponFlags & WIF_WIMPY_WEAPON) || weap->AmmoType1 != NULL) { item->Destroy (); invp = lastinvp; } } } } msg = GStrings("TXT_CHEATIDKFA"); break; case CHT_NOWUDIE: cht_Suicide (player); msg = GStrings("TXT_CHEATIDDQD"); break; case CHT_ALLARTI: for (int i=0; i<25; i++) { cht_Give (player, "artifacts"); } msg = GStrings("TXT_CHEATARTIFACTS3"); break; case CHT_PUZZLE: cht_Give (player, "puzzlepieces"); msg = GStrings("TXT_CHEATARTIFACTS3"); break; case CHT_MDK: if (player->mo == NULL) { Printf ("What do you want to kill outside of a game?\n"); } else if (!deathmatch) { // Don't allow this in deathmatch even with cheats enabled, because it's // a very very cheap kill. P_LineAttack (player->mo, player->mo->Angles.Yaw, PLAYERMISSILERANGE, P_AimLineAttack (player->mo, player->mo->Angles.Yaw, PLAYERMISSILERANGE), TELEFRAG_DAMAGE, NAME_MDK, NAME_BulletPuff); } break; case CHT_DONNYTRUMP: cht_Give (player, "HealthTraining"); msg = GStrings("TXT_MIDASTOUCH"); break; case CHT_LEGO: if (player->mo != NULL && player->health >= 0) { int oldpieces = ASigil::GiveSigilPiece (player->mo); item = player->mo->FindInventory (RUNTIME_CLASS(ASigil)); if (item != NULL) { if (oldpieces == 5) { item->Destroy (); } else { player->PendingWeapon = static_cast<AWeapon *> (item); } } } break; case CHT_PUMPUPH: cht_Give (player, "MedPatch"); cht_Give (player, "MedicalKit"); cht_Give (player, "SurgeryKit"); msg = GStrings("TXT_GOTSTUFF"); break; case CHT_PUMPUPP: cht_Give (player, "AmmoSatchel"); msg = GStrings("TXT_GOTSTUFF"); break; case CHT_PUMPUPS: cht_Give (player, "UpgradeStamina", 10); cht_Give (player, "UpgradeAccuracy"); msg = GStrings("TXT_GOTSTUFF"); break; case CHT_CLEARFROZENPROPS: player->cheats &= ~(CF_FROZEN|CF_TOTALLYFROZEN); msg = "Frozen player properties turned off"; break; case CHT_FREEZE: bglobal.changefreeze ^= 1; if (bglobal.freeze ^ bglobal.changefreeze) { msg = GStrings("TXT_FREEZEON"); } else { msg = GStrings("TXT_FREEZEOFF"); } break; } if (!*msg) // [SO] Don't print blank lines! return; if (player == &players[consoleplayer]) Printf ("%s\n", msg); else if (cheat != CHT_CHASECAM) Printf ("%s cheats: %s\n", player->userinfo.GetName(), msg); }
void R_ResetAfterTeleport(player_t *player) { R_ResetViewInterpolation(); R_SmoothPlaying_Reset(player); }