📄 p_mobj.c
字号:
if( !(oldeflags & (MF_TOUCHWATER|MF_UNDERWATER)) && ((mobj->eflags & MF_TOUCHWATER) || (mobj->eflags & MF_UNDERWATER) ) && mobj->type != MT_BLOOD && gamemode!=heretic) P_SpawnSplash (mobj, *rover->topheight); } return; } else mobj->eflags &= ~(MF_UNDERWATER|MF_TOUCHWATER);/* if( (mobj->eflags ^ oldeflags) & MF_TOUCHWATER) CONS_Printf("touchewater %d\n",mobj->eflags & MF_TOUCHWATER ? 1 : 0); if( (mobj->eflags ^ oldeflags) & MF_UNDERWATER) CONS_Printf("underwater %d\n",mobj->eflags & MF_UNDERWATER ? 1 : 0);*/ // blood doesnt make noise when it falls in water if( !(oldeflags & (MF_TOUCHWATER|MF_UNDERWATER)) && ((mobj->eflags & MF_TOUCHWATER) || (mobj->eflags & MF_UNDERWATER) ) && mobj->type != MT_BLOOD && demoversion<132 ) P_SpawnSplash (mobj, z); //SoM: 3/17/2000}//===========================================================================//// 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 < -8*FRACUNIT && !mo->player->chickenTics) { S_StartSound(mo, sfx_oof); }}//// P_MobjThinker//void P_MobjThinker (mobj_t* mobj){ boolean checkedpos = false; //added:22-02-98: // check mobj against possible water content, before movement code P_MobjCheckWater (mobj); // // momentum movement //#ifdef CLIENTPREDICTION2 // move player mobj (not the spirit) to spirit position (sent by ticcmd) if((mobj->type==MT_PLAYER) && (mobj->player) && ((mobj->player->cmd.angleturn&(TICCMD_XY|TICCMD_RECEIVED))==(TICCMD_XY|TICCMD_RECEIVED)) && (mobj->player->playerstate == PST_LIVE) && demoversion>130) { int oldx = mobj->x, oldy = mobj->y; if( oldx!=mobj->player->cmd.x || oldy!=mobj->player->cmd.y ) { mobj->eflags |= MF_NOZCHECKING; // cross special lines and pick up things if(!P_TryMove (mobj, mobj->player->cmd.x, mobj->player->cmd.y, true)) { // P_TryMove fail mean cannot change mobj position to requestied position // the mobj is blocked by something if (mobj->player-players==consoleplayer) { // reset spirit possition CL_ResetSpiritPosition(mobj); //if(devparm) CONS_Printf("\2MissPrediction\n"); } } mobj->eflags &= ~MF_NOZCHECKING; } P_XYFriction (mobj, oldx, oldy, false); } else#endif if ( mobj->momx || mobj->momy || (mobj->flags&MF_SKULLFLY) ) { P_XYMovement (mobj); checkedpos = true; // FIXME: decent NOP/NULL/Nil function pointer please. if ((mobj->thinker.function.acv == (actionf_v) (-1))) return; // mobj was removed } if(mobj->flags2&MF2_FLOATBOB) { // Floating item bobbing motion mobj->z = mobj->floorz+FloatBobOffsets[(mobj->health++)&63]; } else //added:28-02-98: always do the gravity bit now, that's simpler // BUT CheckPosition only if wasn't do before. if ( (mobj->eflags & MF_ONGROUND)==0 || (mobj->z != mobj->floorz) || mobj->momz ) { // BP: since version 1.31 we use heretic z-cheching code // kept old code for backward demo compatibility if (demoversion <131) { // if didnt check things Z while XYMovement, do the necessary now if (!checkedpos && (demoversion>=112)) { // FIXME : should check only with things, not lines P_CheckPosition (mobj, mobj->x, mobj->y); mobj->floorz = tmfloorz; mobj->ceilingz = tmceilingz; if (tmfloorthing) mobj->eflags &= ~MF_ONGROUND; //not on real floor else mobj->eflags |= MF_ONGROUND; // now mobj->floorz should be the current sector's z floor // or a valid thing's top z } P_ZMovement (mobj); } else if(mobj->flags2&MF2_PASSMOBJ) { mobj_t *onmo; onmo = P_CheckOnmobj(mobj); if(!onmo) { P_ZMovement(mobj); if( mobj->player && mobj->flags&MF2_ONMOBJ ) mobj->flags2 &= ~MF2_ONMOBJ; } else { if(mobj->player) { if(mobj->momz < -8*FRACUNIT && !(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; } } } } else P_ZMovement(mobj); // FIXME: decent NOP/NULL/Nil function pointer please. if (mobj->thinker.function.acv == (actionf_v) (-1)) return; // mobj was removed } else mobj->eflags &= ~MF_JUSTHITFLOOR; // SoM: Floorhuggers stay on the floor allways... // BP: tested here but never set ?! if(mobj->info->flags & MF_FLOORHUGGER) { mobj->z = mobj->floorz; } // cycle through states, // calling action functions at transitions if (mobj->tics != -1) { mobj->tics--; // you can cycle through multiple states in a tic if (!mobj->tics) if (!P_SetMobjState (mobj, mobj->state->nextstate) ) return; // freed itself } else { // check for nightmare respawn if (!cv_respawnmonsters.value) return; if (! (mobj->flags & MF_COUNTKILL) ) return; mobj->movecount++; if (mobj->movecount < cv_respawnmonsterstime.value*TICRATE) return; if ( leveltime % (32*NEWTICRATERATIO) ) return; if (P_Random () > 4) return; P_NightmareRespawn (mobj); }}void P_MobjNullThinker (mobj_t* mobj){}//// 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; 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->health = info->spawnhealth; if (gameskill != sk_nightmare) mobj->reactiontime = info->reactiontime; if( demoversion<129 && mobj->type != MT_CHASECAM) mobj->lastlook = P_Random () % MAXPLAYERS; else mobj->lastlook = -1; // stuff moved in P_enemy.P_LookForPlayer // do not set the state with P_SetMobjState, // because action routines can not be called yet st = &states[info->spawnstate]; mobj->state = st; mobj->tics = st->tics; mobj->sprite = st->sprite; mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits.. mobj->touching_sectorlist = NULL; //SoM: 4/7/2000 mobj->friction = ORIG_FRICTION; //SoM: 4/7/2000 // BP: SoM right ? if not ajust in p_saveg line 625 and 979 mobj->movefactor = ORIG_FRICTION_FACTOR; // set subsector and/or block links P_SetThingPosition (mobj); mobj->floorz = mobj->subsector->sector->floorheight; mobj->ceilingz = mobj->subsector->sector->ceilingheight; //added:27-02-98: if ONFLOORZ, stack the things one on another // so they do not occupy the same 3d space // allow for some funny thing arrangements! if (z == ONFLOORZ) { //if (!P_CheckPosition(mobj,x,y)) // we could send a message to the console here, saying // "no place for spawned thing"... //added:28-02-98: defaults onground mobj->eflags |= MF_ONGROUND; //added:28-02-98: dirty hack : dont stack monsters coz it blocks // moving floors and anyway whats the use of it? /*if (mobj->flags & MF_NOBLOOD) { mobj->z = mobj->floorz; // first check the tmfloorz P_CheckPosition(mobj,x,y); mobj->z = tmfloorz+FRACUNIT; // second check at the good z pos P_CheckPosition(mobj,x,y); mobj->floorz = tmfloorz; mobj->ceilingz = tmsectorceilingz; mobj->z = tmfloorz; // thing not on solid ground if (tmfloorthing) mobj->eflags &= ~MF_ONGROUND; //if (mobj->type == MT_BARREL) // fprintf(stderr,"barrel at z %d floor %d ceiling %d\n",mobj->z,mobj->floorz,mobj->ceilingz); } else*/ mobj->z = mobj->floorz; } else if (z == ONCEILINGZ) mobj->z = mobj->ceilingz - mobj->info->height; else if(z == FLOATRANDZ) { fixed_t 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; } else { //CONS_Printf("mobj spawned at z %d\n",z>>16); mobj->z = z; } if(mobj->flags2&MF2_FOOTCLIP && P_GetThingFloorType(mobj) != FLOOR_SOLID && mobj->floorz == mobj->subsector->sector->floorheight && gamemode == heretic ) mobj->flags2 |= MF2_FEETARECLIPPED; else mobj->flags2 &= ~MF2_FEETARECLIPPED; // added 16-6-98: special hack for spirit if(mobj->type == MT_SPIRIT) mobj->thinker.function.acv = (actionf_p1)P_MobjNullThinker; else { mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker; P_AddThinker (&mobj->thinker); } return mobj;}//// P_RemoveMobj//mapthing_t *itemrespawnque[ITEMQUESIZE];tic_t itemrespawntime[ITEMQUESIZE];int iquehead;int iquetail;void P_RemoveMobj (mobj_t* mobj){ if ((mobj->flags & MF_SPECIAL) && !(mobj->flags & MF_DROPPED) && (mobj->type != MT_INV) && (mobj->type != MT_INS)) { itemrespawnque[iquehead] = mobj->spawnpoint; itemrespawntime[iquehead] = leveltime; iquehead = (iquehead+1)&(ITEMQUESIZE-1); // lose one off the end? if (iquehead == iquetail) iquetail = (iquetail+1)&(ITEMQUESIZE-1); } // unlink from sector and block lists P_UnsetThingPosition (mobj); //SoM: 4/7/2000: Remove touching_sectorlist from mobj. if(sector_list) { P_DelSeclist(sector_list); sector_list = NULL; } // stop any playing sound S_StopSound (mobj); // free block P_RemoveThinker ((thinker_t*)mobj);}consvar_t cv_itemrespawntime={"respawnitemtime","30",CV_NETVAR,CV_Unsigned};consvar_t cv_itemrespawn ={"respawnitem" , "0",CV_NETVAR,CV_OnOff};//// P_RespawnSpecials//void P_RespawnSpecials (void){ fixed_t x; fixed_t y; fixed_t z; mobj_t* mo; mapthing_t* mthing; int i; // only respawn items in deathmatch if (!cv_itemrespawn.value) return; // // nothing left to respawn? if (iquehead == iquetail) return; // the first item in the queue is the first to respawn // wait at least 30 seconds if (leveltime - itemrespawntime[iquetail] < (tic_t)cv_itemrespawntime.value*TICRATE) return; mthing = itemrespawnque[iquetail]; x = mthing->x << FRACBITS; y = mthing->y << FRACBITS; // spawn a teleport fog at the new spot if( gamemode !=heretic ) { subsector_t* ss = R_PointInSubsector (x,y); mo = P_SpawnMobj (x, y, ss->sector->floorheight , MT_IFOG); S_StartSound (mo, sfx_itmbk); } // find which type to spawn for (i=0 ; i< NUMMOBJTYPES ; i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -