void P_InitPlayerClassInfo(void) { PCLASS_INFO(PCLASS_FIGHTER)->niceName = GET_TXT(TXT_PLAYERCLASS1); PCLASS_INFO(PCLASS_CLERIC)->niceName = GET_TXT(TXT_PLAYERCLASS2); PCLASS_INFO(PCLASS_MAGE)->niceName = GET_TXT(TXT_PLAYERCLASS3); PCLASS_INFO(PCLASS_PIG)->niceName = GET_TXT(TXT_PLAYERCLASS4); }
/** * The player can fire the weapon or change to another weapon at this time. * Follows after getting weapon up, or after previous attack/fire sequence. */ void C_DECL A_WeaponReady(player_t* player, pspdef_t* psp) { weaponmodeinfo_t* wminfo; // Enable the pspr Y offset (might be disabled in A_Lower). DD_SetInteger(DD_WEAPON_OFFSET_SCALE_Y, 1000); // Get out of attack state. if(player->plr->mo->state == &STATES[PCLASS_INFO(player->class_)->attackState] || player->plr->mo->state == &STATES[PCLASS_INFO(player->class_)->attackEndState]) { P_MobjChangeState(player->plr->mo, PCLASS_INFO(player->class_)->normalState); } if(player->readyWeapon != WT_NOCHANGE) { wminfo = WEAPON_INFO(player->readyWeapon, player->class_, 0); // A weaponready sound? if(psp->state == &STATES[wminfo->states[WSN_READY]] && wminfo->readySound) S_StartSound(wminfo->readySound, player->plr->mo); // Check for change. If player is dead, put the weapon away. if(player->pendingWeapon != WT_NOCHANGE || !player->health) { // (pending weapon should allready be validated) P_SetPsprite(player, ps_weapon, wminfo->states[WSN_DOWN]); return; } } // Check for autofire. if(player->brain.attack) { wminfo = WEAPON_INFO(player->readyWeapon, player->class_, 0); if(!player->attackDown || wminfo->autoFire) { player->attackDown = true; P_FireWeapon(player); return; } } else player->attackDown = false; // Bob the weapon based on movement speed. R_GetWeaponBob(player - players, &psp->pos[0], &psp->pos[1]); // Psprite state. player->plr->pSprites[0].state = DDPSP_BOBBING; }
/** * Determines whether the player's state is one of the walking states. * * @param pl Player whose state to check. * * @return @c true, if the player is walking. */ boolean P_PlayerInWalkState(player_t* pl) { if(!pl->plr->mo) return false; /// @todo Implementation restricts possibilities for modifying behavior solely with state definitions. #if __JDOOM__ return pl->plr->mo->state - STATES - PCLASS_INFO(pl->class_)->runState < 4; #endif #if __JHERETIC__ return pl->plr->mo->state - STATES - PCLASS_INFO(pl->class_)->runState < 4; #endif #if __JHEXEN__ return ((unsigned) ((pl->plr->mo->state - STATES) - PCLASS_INFO(pl->class_)->runState) < 4); #endif #if __JDOOM64__ return pl->plr->mo->state - STATES - PCLASS_INFO(pl->class_)->runState < 4; #endif }
void P_FireWeapon(player_t *player) { statenum_t newstate; if(!P_CheckAmmo(player)) return; // Psprite state. player->plr->pSprites[0].state = DDPSP_FIRE; P_MobjChangeState(player->plr->mo, PCLASS_INFO(player->class_)->attackState); newstate = weaponInfo[player->readyWeapon][player->class_].mode[0].states[WSN_ATTACK]; P_SetPsprite(player, ps_weapon, newstate); P_NoiseAlert(player->plr->mo, player->plr->mo); }
/** * 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); } }
void Mobj_XYMoveStopping(mobj_t *mo) { DENG_ASSERT(mo != 0); player_t *player = mo->player; if(player && (P_GetPlayerCheats(player) & CF_NOMOMENTUM)) { // Debug option for no sliding at all. mo->mom[MX] = mo->mom[MY] = 0; return; } if(mo->flags & (MF_MISSILE | MF_SKULLFLY)) { // No friction for missiles. return; } if(mo->origin[VZ] > mo->floorZ && !mo->onMobj && !(mo->flags2 & MF2_FLY)) { // No friction when falling. return; } #ifndef __JHEXEN__ if(cfg.slidingCorpses) { // $dropoff_fix: Add objects falling off ledges. Does not apply to players! if(((mo->flags & MF_CORPSE) || (mo->intFlags & MIF_FALLING)) && !mo->player) { // Do not stop sliding if halfway off a step with some momentum. if(!INRANGE_OF(mo->mom[MX], 0, DROPOFFMOMENTUM_THRESHOLD) || !INRANGE_OF(mo->mom[MY], 0, DROPOFFMOMENTUM_THRESHOLD)) { if(!FEQUAL(mo->floorZ, P_GetDoublep(Mobj_Sector(mo), DMU_FLOOR_HEIGHT))) return; } } } #endif bool isVoodooDoll = Mobj_IsVoodooDoll(mo); bool belowWalkStop = (INRANGE_OF(mo->mom[MX], 0, WALKSTOP_THRESHOLD) && INRANGE_OF(mo->mom[MY], 0, WALKSTOP_THRESHOLD)); bool belowStandSpeed = false; bool isMovingPlayer = false; if(player) { belowStandSpeed = (INRANGE_OF(mo->mom[MX], 0, STANDSPEED) && INRANGE_OF(mo->mom[MY], 0, STANDSPEED)); isMovingPlayer = (!FEQUAL(player->plr->forwardMove, 0) || !FEQUAL(player->plr->sideMove, 0)); } // Stop player walking animation (only real players). if(!isVoodooDoll && player && belowStandSpeed && !isMovingPlayer && !IS_NETWORK_SERVER) // Netgame servers use logic elsewhere for player animation. { // If in a walking frame, stop moving. if(P_PlayerInWalkState(player)) { P_MobjChangeState(player->plr->mo, statenum_t(PCLASS_INFO(player->class_)->normalState)); } } // Apply friction. if(belowWalkStop && !isMovingPlayer) { // $voodoodolls: Do not zero mom for voodoo dolls! if(!isVoodooDoll) { // Momentum is below the walkstop threshold; stop it completely. mo->mom[MX] = mo->mom[MY] = 0; // $voodoodolls: Stop view bobbing if this isn't a voodoo doll. if(player) player->bob = 0; } } else { coord_t friction = Mobj_Friction(mo); mo->mom[MX] *= friction; mo->mom[MY] *= friction; } }
void C_DECL A_GunFlash(player_t *player, pspdef_t *psp) { P_MobjChangeState(player->plr->mo, PCLASS_INFO(player->class_)->attackEndState); P_SetPsprite(player, ps_flash, weaponInfo[player->readyWeapon][player->class_].mode[0].states[WSN_FLASH]); }