📄 p_mobj.c
字号:
{ if(mo->floorz != mo->subsector->sector->floorheight) { return; } } } if(mo->momx > -STOPSPEED && mo->momx < STOPSPEED && mo->momy > -STOPSPEED && mo->momy < STOPSPEED && (!player || (player->cmd.forwardmove == 0 && player->cmd.sidemove == 0))) { // If in a walking frame, stop moving if(player) { if((unsigned)((player->mo->state-states) -PStateRun[player->class]) < 4) { P_SetMobjState(player->mo, PStateNormal[player->class]); } } mo->momx = 0; mo->momy = 0; } else { if(mo->flags2&MF2_FLY && !(mo->z <= mo->floorz) &&!(mo->flags2&MF2_ONMOBJ)) { mo->momx = FixedMul(mo->momx, FRICTION_FLY); mo->momy = FixedMul(mo->momy, FRICTION_FLY); } else if(P_GetThingFloorType(mo) == FLOOR_ICE) { mo->momx = FixedMul(mo->momx, FRICTION_LOW); mo->momy = FixedMul(mo->momy, FRICTION_LOW); } else { mo->momx = FixedMul(mo->momx, FRICTION_NORMAL); mo->momy = FixedMul(mo->momy, FRICTION_NORMAL); } }}// Move this to p_inter ***void P_MonsterFallingDamage(mobj_t *mo){ int damage; int mom; mom = abs(mo->momz); if(mom > 35*FRACUNIT) { // automatic death damage=10000; } else { damage = ((mom - (23*FRACUNIT) )*6)>>FRACBITS; } damage=10000; // always kill 'em P_DamageMobj(mo, NULL, NULL, damage);}/*================= P_ZMovement================*/void P_ZMovement(mobj_t *mo){ int dist; int delta;//// check for smooth step up// if (mo->player && mo->z < mo->floorz) { mo->player->viewheight -= mo->floorz-mo->z; mo->player->deltaviewheight = (VIEWHEIGHT - mo->player->viewheight)>>3; } //// adjust height// mo->z += mo->momz; if(mo->flags&MF_FLOAT && mo->target) { // float down towards target if too close if(!(mo->flags&MF_SKULLFLY) && !(mo->flags&MF_INFLOAT)) { dist = P_AproxDistance(mo->x-mo->target->x, mo->y-mo->target->y); delta =( mo->target->z+(mo->height>>1))-mo->z; if (delta < 0 && dist < -(delta*3)) mo->z -= FLOATSPEED; else if (delta > 0 && dist < (delta*3)) mo->z += FLOATSPEED; } } if(mo->player && mo->flags2&MF2_FLY && !(mo->z <= mo->floorz) && leveltime&2) { mo->z += finesine[(FINEANGLES/20*leveltime>>2)&FINEMASK]; }//// clip movement// if(mo->z <= mo->floorz) { // Hit the floor if(mo->flags&MF_MISSILE) { mo->z = mo->floorz; if(mo->flags2&MF2_FLOORBOUNCE) { P_FloorBounceMissile(mo); return; } else if(mo->type == MT_HOLY_FX) { // The spirit struck the ground mo->momz = 0; P_HitFloor(mo); return; } else if(mo->type == MT_MNTRFX2 || mo->type == MT_LIGHTNING_FLOOR) { // Minotaur floor fire can go up steps return; } else { P_HitFloor(mo); P_ExplodeMissile(mo); return; } } if(mo->flags&MF_COUNTKILL) // Blasted mobj falling { if(mo->momz < -(23*FRACUNIT)) { P_MonsterFallingDamage(mo); } } if(mo->z-mo->momz > mo->floorz) { // Spawn splashes, etc. P_HitFloor(mo); } mo->z = mo->floorz; if(mo->momz < 0) { if(mo->flags2&MF2_ICEDAMAGE && mo->momz < -GRAVITY*8) { mo->tics = 1; mo->momx = 0; mo->momy = 0; mo->momz = 0; return; } if(mo->player) { mo->player->jumpTics = 7;// delay any jumping for a short time if(mo->momz < -GRAVITY*8 && !(mo->flags2&MF2_FLY)) { // squat down mo->player->deltaviewheight = mo->momz>>3; if(mo->momz < -23*FRACUNIT) { P_FallingDamage(mo->player); P_NoiseAlert(mo, mo); } else if(mo->momz < -GRAVITY*12 && !mo->player->morphTics) { S_StartSound(mo, SFX_PLAYER_LAND); switch(mo->player->class) { case PCLASS_FIGHTER: S_StartSound(mo, SFX_PLAYER_FIGHTER_GRUNT); break; case PCLASS_CLERIC: S_StartSound(mo, SFX_PLAYER_CLERIC_GRUNT); break; case PCLASS_MAGE: S_StartSound(mo, SFX_PLAYER_MAGE_GRUNT); break; default: break; } } else if ((P_GetThingFloorType(mo) < FLOOR_LIQUID) && (!mo->player->morphTics)) { S_StartSound(mo, SFX_PLAYER_LAND); }#ifdef __WATCOMC__ if(!useexterndriver) { mo->player->centering = true; }#else mo->player->centering = true;#endif } } else if(mo->type >= MT_POTTERY1 && mo->type <= MT_POTTERY3) { P_DamageMobj(mo, NULL, NULL, 25); } else if(mo->flags&MF_COUNTKILL) { if(mo->momz < -23*FRACUNIT) { // Doesn't get here } } mo->momz = 0; } if(mo->flags&MF_SKULLFLY) { // The skull slammed into something mo->momz = -mo->momz; } if(mo->info->crashstate && (mo->flags&MF_CORPSE) && !(mo->flags2&MF2_ICEDAMAGE)) { P_SetMobjState(mo, mo->info->crashstate); return; } } else if(mo->flags2&MF2_LOGRAV) { if(mo->momz == 0) mo->momz = -(GRAVITY>>3)*2; else mo->momz -= GRAVITY>>3; } else if (! (mo->flags & MF_NOGRAVITY) ) { if (mo->momz == 0) mo->momz = -GRAVITY*2; else mo->momz -= GRAVITY; } if (mo->z + mo->height > mo->ceilingz) { // hit the ceiling if (mo->momz > 0) mo->momz = 0; mo->z = mo->ceilingz - mo->height; if(mo->flags2&MF2_FLOORBOUNCE) { // Maybe reverse momentum here for ceiling bounce // Currently won't happen if(mo->info->seesound) { S_StartSound(mo, mo->info->seesound); } return; } if (mo->flags & MF_SKULLFLY) { // the skull slammed into something mo->momz = -mo->momz; } if(mo->flags&MF_MISSILE) { if(mo->type == MT_LIGHTNING_CEILING) { return; } if(mo->subsector->sector->ceilingpic == skyflatnum) { if(mo->type == MT_BLOODYSKULL) { mo->momx = mo->momy = 0; mo->momz = -FRACUNIT; } else if(mo->type == MT_HOLY_FX) { P_ExplodeMissile(mo); } else { P_RemoveMobj(mo); } return; } P_ExplodeMissile(mo); return; } }}//----------------------------------------------------------------------------//// PROC P_BlasterMobjThinker//////----------------------------------------------------------------------------void P_BlasterMobjThinker(mobj_t *mobj){ int i; fixed_t xfrac; fixed_t yfrac; fixed_t zfrac; fixed_t z; boolean changexy; mobj_t *mo; // Handle movement if(mobj->momx || mobj->momy || (mobj->z != mobj->floorz) || mobj->momz) { xfrac = mobj->momx>>3; yfrac = mobj->momy>>3; zfrac = mobj->momz>>3; changexy = xfrac || yfrac; for(i = 0; i < 8; i++) { if(changexy) { if(!P_TryMove(mobj, mobj->x+xfrac, mobj->y+yfrac)) { // Blocked move P_ExplodeMissile(mobj); return; } } mobj->z += zfrac; if(mobj->z <= mobj->floorz) { // Hit the floor mobj->z = mobj->floorz; P_HitFloor(mobj); P_ExplodeMissile(mobj); return; } if(mobj->z+mobj->height > mobj->ceilingz) { // Hit the ceiling mobj->z = mobj->ceilingz-mobj->height; P_ExplodeMissile(mobj); return; } if(changexy) { if(mobj->type == MT_MWAND_MISSILE && (P_Random() < 128)) { z = mobj->z-8*FRACUNIT; if(z < mobj->floorz) { z = mobj->floorz; } P_SpawnMobj(mobj->x, mobj->y, z, MT_MWANDSMOKE); } else if(!--mobj->special1) { mobj->special1 = 4; z = mobj->z-12*FRACUNIT; if(z < mobj->floorz) { z = mobj->floorz; } mo = P_SpawnMobj(mobj->x, mobj->y, z, MT_CFLAMEFLOOR); if(mo) { mo->angle = mobj->angle; } } } } } // Advance the state if(mobj->tics != -1) { mobj->tics--; while(!mobj->tics) { if(!P_SetMobjState(mobj, mobj->state->nextstate)) { // mobj was removed return; } } }}//===========================================================================//// PlayerLandedOnThing////===========================================================================static void PlayerLandedOnThing(mobj_t *mo, mobj_t *onmobj){ mo->player->deltaviewheight = mo->momz>>3; if(mo->momz < -23*FRACUNIT) { P_FallingDamage(mo->player); P_NoiseAlert(mo, mo); } else if(mo->momz < -GRAVITY*12 && !mo->player->morphTics) { S_StartSound(mo, SFX_PLAYER_LAND); switch(mo->player->class) { case PCLASS_FIGHTER: S_StartSound(mo, SFX_PLAYER_FIGHTER_GRUNT); break; case PCLASS_CLERIC: S_StartSound(mo, SFX_PLAYER_CLERIC_GRUNT); break; case PCLASS_MAGE: S_StartSound(mo, SFX_PLAYER_MAGE_GRUNT); break; default: break; } } else if(!mo->player->morphTics) { S_StartSound(mo, SFX_PLAYER_LAND); }#ifdef __WATCOMC__ if(!useexterndriver) { mo->player->centering = true; }#else mo->player->centering = true;#endif}//----------------------------------------------------------------------------//// PROC P_MobjThinker////----------------------------------------------------------------------------void P_MobjThinker(mobj_t *mobj){ mobj_t *onmo;/* // Reset to not blasted when momentums are gone if((mobj->flags2&MF2_BLASTED) && (!(mobj->momx)) && (!(mobj->momy))) ResetBlasted(mobj);*/ // Handle X and Y momentums BlockingMobj = NULL; if(mobj->momx || mobj->momy || (mobj->flags&MF_SKULLFLY)) { P_XYMovement(mobj); if(mobj->thinker.function == (think_t)-1) { // mobj was removed return; } } else if(mobj->flags2&MF2_BLASTED) { // Reset to not blasted when momentums are gone ResetBlasted(mobj); } if(mobj->flags2&MF2_FLOATBOB) { // Floating item bobbing motion (special1 is height) mobj->z = mobj->floorz + mobj->special1 + FloatBobOffsets[(mobj->health++)&63]; } else if((mobj->z != mobj->floorz) || mobj->momz || BlockingMobj) { // Handle Z momentum and gravity if(mobj->flags2&MF2_PASSMOBJ) { if(!(onmo = P_CheckOnmobj(mobj))) { P_ZMovement(mobj); if(mobj->player && mobj->flags&MF2_ONMOBJ) { mobj->flags2 &= ~MF2_ONMOBJ; } } else { if(mobj->player) { if(mobj->momz < -GRAVITY*8 && !(mobj->flags2&MF2_FLY)) { PlayerLandedOnThing(mobj, onmo); } if(onmo->z+onmo->height-mobj->z <= 24*FRACUNIT) { mobj->player->viewheight -= onmo->z+onmo->height -mobj->z; mobj->player->deltaviewheight = (VIEWHEIGHT-mobj->player->viewheight)>>3; mobj->z = onmo->z+onmo->height; mobj->flags2 |= MF2_ONMOBJ; mobj->momz = 0; } else { // hit the bottom of the blocking mobj mobj->momz = 0; } }/* Landing on another player, and mimicking his movements if(mobj->player && onmo->player) { mobj->momx = onmo->momx; mobj->momy = onmo->momy; if(onmo->z < onmo->floorz) { mobj->z += onmo->floorz-onmo->z; if(onmo->player) { onmo->player->viewheight -= onmo->floorz-onmo->z; onmo->player->deltaviewheight = (VIEWHEIGHT- onmo->player->viewheight)>>3; } onmo->z = onmo->floorz; } }*/ } } else { P_ZMovement(mobj); } if(mobj->thinker.function == (think_t)-1) { // mobj was removed return; } } // Cycle through states, calling action functions at transitions if(mobj->tics != -1) { mobj->tics--; // you can cycle through multiple states in a tic while(!mobj->tics) { if(!P_SetMobjState(mobj, mobj->state->nextstate)) { // mobj was removed return; } } }}//==========================================================================//// P_SpawnMobj////==========================================================================mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type){ mobj_t *mobj; state_t *st; mobjinfo_t *info; fixed_t space; mobj = Z_Malloc(sizeof(*mobj), PU_LEVEL, NULL); memset(mobj, 0, sizeof(*mobj)); info = &mobjinfo[type]; mobj->type = type; mobj->info = info; mobj->x = x; mobj->y = y; mobj->radius = info->radius; mobj->height = info->height; mobj->flags = info->flags; mobj->flags2 = info->flags2; mobj->damage = info->damage; mobj->health = info->spawnhealth; if(gameskill != sk_nightmare) { mobj->reactiontime = info->reactiontime; } mobj->lastlook = P_Random()%MAXPLAYERS; // Set the state, but do not use P_SetMobjState, because action // routines can't be called yet. If the spawnstate has an action // routine, it will not be called. st = &states[info->spawnstate]; mobj->state = st; mobj->tics = st->tics; mobj->sprite = st->sprite; mobj->frame = st->frame; // Set subsector and/or block links. P_SetThingPosition(mobj); mobj->floorz = mobj->subsector->sector->floorheight; mobj->ceilingz = mobj->subsector->sector->ceilingheight; if(z == ONFLOORZ) { mobj->z = mobj->floorz; } else if(z == ONCEILINGZ) { mobj->z = mobj->ceilingz-mobj->info->height; } else if(z == FLOATRANDZ) { space = ((mobj->ceilingz)-(mobj->info->height))-mobj->floorz; if(space > 48*FRACUNIT) { space -= 40*FRACUNIT; mobj->z = ((space*P_Random())>>8)+mobj->floorz+40*FRACUNIT; } else { mobj->z = mobj->floorz; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -