int P_CameraXYMovement(mobj_t *mo) { if(!P_MobjIsCamera(mo)) return false; #if __JDOOM__ || __JDOOM64__ if(mo->flags & MF_NOCLIP || // This is a very rough check! Sometimes you get stuck in things. P_CheckPositionXYZ(mo, mo->origin[VX] + mo->mom[MX], mo->origin[VY] + mo->mom[MY], mo->origin[VZ])) { #endif P_MobjUnsetOrigin(mo); mo->origin[VX] += mo->mom[MX]; mo->origin[VY] += mo->mom[MY]; P_MobjSetOrigin(mo); P_CheckPositionXY(mo, mo->origin[VX], mo->origin[VY]); mo->floorZ = tmFloorZ; mo->ceilingZ = tmCeilingZ; #if __JDOOM__ || __JDOOM64__ } #endif // Friction. if(!INRANGE_OF(mo->player->brain.forwardMove, 0, CAMERA_FRICTION_THRESHOLD) || !INRANGE_OF(mo->player->brain.sideMove, 0, CAMERA_FRICTION_THRESHOLD) || !INRANGE_OF(mo->player->brain.upMove, 0, CAMERA_FRICTION_THRESHOLD)) { // While moving; normal friction applies. mo->mom[MX] *= FRICTION_NORMAL; mo->mom[MY] *= FRICTION_NORMAL; } else { // Else lose momentum, quickly!. mo->mom[MX] *= FRICTION_HIGH; mo->mom[MY] *= FRICTION_HIGH; } return true; }
int P_CameraZMovement(mobj_t *mo) { if(!P_MobjIsCamera(mo)) return false; mo->origin[VZ] += mo->mom[MZ]; // Friction. if(!INRANGE_OF(mo->player->brain.forwardMove, 0, CAMERA_FRICTION_THRESHOLD) || !INRANGE_OF(mo->player->brain.sideMove, 0, CAMERA_FRICTION_THRESHOLD) || !INRANGE_OF(mo->player->brain.upMove, 0, CAMERA_FRICTION_THRESHOLD)) { // While moving; normal friction applies. mo->mom[MZ] *= FRICTION_NORMAL; } else { // Else, lose momentum quickly!. mo->mom[MZ] *= FRICTION_HIGH; } return true; }
/** * Changes the class of the given player. Will not work if the player * is currently morphed. */ void P_PlayerChangeClass(player_t *player, playerclass_t newClass) { int i; DENG_ASSERT(player != 0); if(newClass < PCLASS_FIRST || newClass >= NUM_PLAYER_CLASSES) return; // Don't change if morphed. if(player->morphTics) return; if(!PCLASS_INFO(newClass)->userSelectable) return; player->class_ = newClass; cfg.playerClass[player - players] = newClass; P_ClassForPlayerWhenRespawning(player - players, true /*clear change request*/); // Take away armor. for(i = 0; i < NUMARMOR; ++i) { player->armorPoints[i] = 0; } player->update |= PSF_ARMOR_POINTS; P_PostMorphWeapon(player, WT_FIRST); if(player->plr->mo) { // Respawn the player and destroy the old mobj. mobj_t* oldMo = player->plr->mo; P_SpawnPlayer(player - players, newClass, oldMo->origin[VX], oldMo->origin[VY], oldMo->origin[VZ], oldMo->angle, 0, P_MobjIsCamera(oldMo), true); P_MobjRemove(oldMo, true); } }
dd_bool Mobj_LookForPlayers(mobj_t *mo, dd_bool allAround) { int const playerCount = P_CountPlayersInGame(); // Nobody to target? if(!playerCount) return false; int const from = mo->lastLook % MAXPLAYERS; int const to = (from + MAXPLAYERS - 1) % MAXPLAYERS; int cand = from; int tries = 0; bool foundTarget = false; for(; cand != to; cand = (cand < (MAXPLAYERS - 1)? cand + 1 : 0)) { player_t *player = players + cand; // Is player in the game? if(!player->plr->inGame) continue; mobj_t *plrmo = player->plr->mo; if(!plrmo) continue; // Do not target camera players. if(P_MobjIsCamera(plrmo)) continue; // Only look ahead a fixed number of times. if(tries++ == 2) break; // Do not target dead players. if(player->health <= 0) continue; // Within sight? if(!P_CheckSight(mo, plrmo)) continue; if(!allAround) { angle_t an = M_PointToAngle2(mo->origin, plrmo->origin); an -= mo->angle; if(an > ANG90 && an < ANG270) { // If real close, react anyway. coord_t dist = M_ApproxDistance(plrmo->origin[VX] - mo->origin[VX], plrmo->origin[VY] - mo->origin[VY]); // Behind us? if(dist > MELEERANGE) continue; } } #if __JHERETIC__ || __JHEXEN__ // If player is invisible we may not detect if too far or randomly. if(plrmo->flags & MF_SHADOW) { if((M_ApproxDistance(plrmo->origin[VX] - mo->origin[VX], plrmo->origin[VY] - mo->origin[VY]) > 2 * MELEERANGE) && M_ApproxDistance(plrmo->mom[MX], plrmo->mom[MY]) < 5) { // Too far; can't detect. continue; } // Randomly overlook the player regardless. if(P_Random() < 225) continue; } #endif #if __JHEXEN__ // Minotaurs do not target their master. if(mo->type == MT_MINOTAUR && mo->tracer && mo->tracer->player == player) continue; #endif // Found our quarry. mo->target = plrmo; foundTarget = true; } // Start looking from here next time. mo->lastLook = cand; return foundTarget; }