📄 p_mobj.c
字号:
if (!P_TryMove (mo, ptryx, ptryy, true)) //SoM: 4/10/2000 { // blocked move // gameplay issue : let the marine move forward while trying // to jump over a small wall // (normally it can not 'walk' while in air) // BP:1.28 no more use Cf_JUMPOVER, but i leave it for backward lmps compatibility if (mo->player) { if (tmfloorz - mo->z > MAXSTEPMOVE) { if (mo->momz > 0) mo->player->cheats |= CF_JUMPOVER; else mo->player->cheats &= ~CF_JUMPOVER; } } if (mo->flags2&MF2_SLIDE) { // try to slide along it P_SlideMove (mo); } else if (mo->flags & MF_MISSILE) { // explode a missile if (ceilingline && ceilingline->backsector && ceilingline->backsector->ceilingpic == skyflatnum && ceilingline->frontsector && ceilingline->frontsector->ceilingpic == skyflatnum && mo->subsector->sector->ceilingheight == mo->ceilingz) if (!boomsupport || mo->z > ceilingline->backsector->ceilingheight)//SoM: 4/7/2000: DEMO'S { // Hack to prevent missiles exploding // against the sky. // Does not handle sky floors. //SoM: 4/3/2000: Check frontsector as well.. if(mo->type == MT_BLOODYSKULL) { mo->momx = mo->momy = 0; mo->momz = -FRACUNIT; } else P_RemoveMobj (mo); return; } // draw damage on wall //SPLAT TEST ----------------------------------------------------------#ifdef WALLSPLATS if (blockingline && demoversion>=129) //set by last P_TryMove() that failed { divline_t divl; divline_t misl; fixed_t frac; P_MakeDivline (blockingline, &divl); misl.x = mo->x; misl.y = mo->y; misl.dx = mo->momx; misl.dy = mo->momy; frac = P_InterceptVector (&divl, &misl); R_AddWallSplat (blockingline, P_PointOnLineSide(mo->x,mo->y,blockingline) ,"A_DMG3", mo->z, frac, SPLATDRAWMODE_SHADE); }#endif // --------------------------------------------------------- SPLAT TEST P_ExplodeMissile (mo); } else mo->momx = mo->momy = 0; } else // hack for playability : walk in-air to jump over a small wall if (mo->player) mo->player->cheats &= ~CF_JUMPOVER; } while (xmove || ymove); // slow down if (player) { if (player->cheats & CF_NOMOMENTUM) { // debug option for no sliding at all mo->momx = mo->momy = 0; return; } else if ((player->cheats & CF_FLYAROUND) || (player->mo->flags2 & MF2_FLY)) { P_XYFriction (mo, oldx, oldy, true); return; }// if(mo->z <= mo->subsector->sector->floorheight)// P_XYFriction (mo, oldx, oldy, false); } if (mo->flags & (MF_MISSILE | MF_SKULLFLY) ) return; // no friction for missiles ever // slow down in water, not too much for playability issues if (demoversion>=128 && (mo->eflags & MF_UNDERWATER)) { mo->momx = FixedMul (mo->momx, FRICTION*3/4); mo->momy = FixedMul (mo->momy, FRICTION*3/4); return; } if (mo->z > mo->floorz && !(mo->flags2&MF2_FLY) && !(mo->flags2&MF2_ONMOBJ)) return; // no friction when airborne if (mo->flags & MF_CORPSE) { // do not stop sliding // if halfway off a step with some momentum if (mo->momx > FRACUNIT/4 || mo->momx < -FRACUNIT/4 || mo->momy > FRACUNIT/4 || mo->momy < -FRACUNIT/4) { if (mo->floorz != mo->subsector->sector->floorheight) return; } } P_XYFriction (mo, oldx, oldy, demoversion<132);}//// P_ZMovement//void P_ZMovement (mobj_t* mo){ fixed_t dist; fixed_t delta; // check for smooth step up#ifdef CLIENTPREDICTION2 if (mo->player && mo->z < mo->floorz && mo->type!=MT_PLAYER)#else if (mo->player && mo->z < mo->floorz && mo->type!=MT_SPIRIT)#endif { mo->player->viewheight -= mo->floorz - mo->z; mo->player->deltaviewheight = ((cv_viewheight.value<<FRACBITS) - 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_MNTRFX2) { // Minotaur floor fire can go up steps return; } else { if( (mo->flags& MF_NOCLIP)==0 ) { P_ExplodeMissile(mo); return; } } } // Spawn splashes, etc. if(mo->z-mo->momz > mo->floorz) P_HitFloor(mo); mo->z = mo->floorz; // Note (id): // somebody left this after the setting momz to 0, // kinda useless there. if (mo->flags & MF_SKULLFLY) { // the skull slammed into something mo->momz = -mo->momz; } if (mo->momz < 0) // falling { if (mo->player && (mo->momz < -8*FRACUNIT) && !(mo->flags2&MF2_FLY)) { // Squat down. // Decrease viewheight for a moment // after hitting the ground (hard), // and utter appropriate sound. mo->player->deltaviewheight = mo->momz>>3; S_StartSound (mo, sfx_oof); } // set it once and not continuously if (mo->z < mo->floorz) mo->eflags |= MF_JUSTHITFLOOR; mo->momz = 0; } if(mo->info->crashstate && (mo->flags&MF_CORPSE)) { P_SetMobjState(mo, mo->info->crashstate); mo->flags &= ~MF_CORPSE; return; } } else if(mo->flags2&MF2_LOGRAV) { if(mo->momz == 0) mo->momz = -(cv_gravity.value>>3)*2; else mo->momz -= cv_gravity.value>>3; } else if (! (mo->flags & MF_NOGRAVITY) ) // Gravity here! { fixed_t gravityadd; //Fab: NOT SURE WHETHER IT IS USEFUL, just put it here too // TO BE SURE there is no problem for the release.. // (this is done in P_Mobjthinker below normally) mo->eflags &= ~MF_JUSTHITFLOOR; gravityadd = -cv_gravity.value/NEWTICRATERATIO; // if waist under water, slow down the fall if ( mo->eflags & MF_UNDERWATER) { if ( mo->eflags & MF_SWIMMING ) gravityadd = 0; // gameplay: no gravity while swimming else gravityadd >>= 2; } else if (mo->momz==0) // mobj at stop, no floor, so feel the push of gravity! gravityadd <<= 1; mo->momz += gravityadd; } if (mo->z + mo->height > mo->ceilingz) { mo->z = mo->ceilingz - mo->height; //added:22-02-98: player avatar hits his head on the ceiling, ouch! if (mo->player && (demoversion>=112) && !(mo->player->cheats & CF_FLYAROUND) && !(mo->flags2 & MF2_FLY) && mo->momz>8*FRACUNIT ) S_StartSound (mo, sfx_ouch); // hit the ceiling if (mo->momz > 0) mo->momz = 0; if (mo->flags & MF_SKULLFLY) { // the skull slammed into something mo->momz = -mo->momz; } if ( (mo->flags & MF_MISSILE) && !(mo->flags & MF_NOCLIP) ) { //SoM: 4/3/2000: Don't explode on the sky! if(demoversion >= 129 && mo->subsector->sector->ceilingpic == skyflatnum && mo->subsector->sector->ceilingheight == mo->ceilingz) { if(mo->type == MT_BLOODYSKULL) { mo->momx = mo->momy = 0; mo->momz = -FRACUNIT; } else P_RemoveMobj(mo); return; } P_ExplodeMissile (mo); return; } } // z friction in water if (demoversion>=128 && ((mo->eflags & MF_TOUCHWATER) || (mo->eflags & MF_UNDERWATER)) && !(mo->flags & (MF_MISSILE | MF_SKULLFLY))) { mo->momz = FixedMul (mo->momz, FRICTION*3/4); }}//// P_NightmareRespawn//voidP_NightmareRespawn (mobj_t* mobj){ fixed_t x; fixed_t y; fixed_t z; subsector_t* ss; mobj_t* mo; mapthing_t* mthing; x = mobj->spawnpoint->x << FRACBITS; y = mobj->spawnpoint->y << FRACBITS; // somthing is occupying it's position? if (!P_CheckPosition (mobj, x, y) ) return; // no respwan // spawn a teleport fog at old spot // because of removal of the body? mo = P_SpawnMobj (mobj->x, mobj->y, mobj->subsector->sector->floorheight+(gamemode == heretic ? TELEFOGHEIGHT : 0), MT_TFOG); // initiate teleport sound S_StartSound (mo, sfx_telept); // spawn a teleport fog at the new spot ss = R_PointInSubsector (x,y); mo = P_SpawnMobj (x, y, ss->sector->floorheight+(gamemode == heretic ? TELEFOGHEIGHT : 0) , MT_TFOG); S_StartSound (mo, sfx_telept); // spawn the new monster mthing = mobj->spawnpoint; // spawn it if (mobj->info->flags & MF_SPAWNCEILING) z = ONCEILINGZ; else z = ONFLOORZ; // inherit attributes from deceased one mo = P_SpawnMobj (x,y,z, mobj->type); mo->spawnpoint = mobj->spawnpoint; mo->angle = ANG45 * (mthing->angle/45); if (mthing->options & MTF_AMBUSH) mo->flags |= MF_AMBUSH; mo->reactiontime = 18; // remove the old monster, P_RemoveMobj (mobj);}consvar_t cv_respawnmonsters = {"respawnmonsters","0",CV_NETVAR,CV_OnOff};consvar_t cv_respawnmonsterstime = {"respawnmonsterstime","12",CV_NETVAR,CV_Unsigned};//// P_MobjCheckWater : check for water, set stuff in mobj_t struct for// movement code later, this is called either by P_MobjThinker() or P_PlayerThink()void P_MobjCheckWater (mobj_t* mobj){ sector_t* sector; fixed_t z; int oldeflags; if( demoversion<128 || mobj->type==MT_SPLASH || mobj->type==MT_SPIRIT) // splash don't do splash return; // // see if we are in water, and set some flags for later // sector = mobj->subsector->sector; z = sector->floorheight; oldeflags = mobj->eflags; //SoM: 3/28/2000: Only use 280 water type of water. Some boom levels get messed up. if ((sector->heightsec > -1 && sector->altheightsec == 1) || (sector->floortype==FLOOR_WATER && sector->heightsec == -1)) { if (sector->heightsec > -1) //water hack z = (sectors[sector->heightsec].floorheight); else z = sector->floorheight + (FRACUNIT/4); // water texture if (mobj->z<=z && mobj->z+mobj->height > z) mobj->eflags |= MF_TOUCHWATER; else mobj->eflags &= ~MF_TOUCHWATER; if (mobj->z+(mobj->height>>1) <= z) mobj->eflags |= MF_UNDERWATER; else mobj->eflags &= ~MF_UNDERWATER; } else if(sector->ffloors) { ffloor_t* rover; mobj->eflags &= ~(MF_UNDERWATER|MF_TOUCHWATER); for(rover = sector->ffloors; rover; rover = rover->next) { if(!(rover->flags & FF_SWIMMABLE) || rover->flags & FF_SOLID) continue; if(*rover->topheight <= mobj->z || *rover->bottomheight > (mobj->z + (mobj->info->height >> 1))) continue; if(mobj->z + mobj->info->height > *rover->topheight) mobj->eflags |= MF_TOUCHWATER; else mobj->eflags &= ~MF_TOUCHWATER; if(mobj->z + (mobj->info->height >> 1) < *rover->topheight) mobj->eflags |= MF_UNDERWATER; else mobj->eflags &= ~MF_UNDERWATER;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -