⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p_mobj.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 5 页
字号:
        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 + -