📄 p_mobj.c
字号:
} else if (mobj->flags2&MF2_FLOATBOB) { mobj->z = mobj->floorz + z; // artifact z passed in as height } else { mobj->z = z; } if(mobj->flags2&MF2_FLOORCLIP && P_GetThingFloorType(mobj) >= FLOOR_LIQUID && mobj->z == mobj->subsector->sector->floorheight) { mobj->floorclip = 10*FRACUNIT; } else { mobj->floorclip = 0; } mobj->thinker.function = P_MobjThinker; P_AddThinker(&mobj->thinker); return(mobj);}//==========================================================================//// P_RemoveMobj////==========================================================================void P_RemoveMobj(mobj_t *mobj){ // Remove from creature queue if(mobj->flags&MF_COUNTKILL && mobj->flags&MF_CORPSE) { A_DeQueueCorpse(mobj); } if(mobj->tid) { // Remove from TID list P_RemoveMobjFromTIDList(mobj); } // Unlink from sector and block lists P_UnsetThingPosition(mobj); // Stop any playing sound S_StopSound(mobj); // Free block P_RemoveThinker((thinker_t *)mobj);}//==========================================================================//// P_SpawnPlayer//// Called when a player is spawned on the level. Most of the player// structure stays unchanged between levels.////==========================================================================void P_SpawnPlayer(mapthing_t *mthing){ player_t *p; fixed_t x, y, z; mobj_t *mobj; if(!playeringame[mthing->type-1]) { // Not playing return; } p = &players[mthing->type-1]; if(p->playerstate == PST_REBORN) { G_PlayerReborn(mthing->type-1); } x = mthing->x << FRACBITS; y = mthing->y << FRACBITS; z = ONFLOORZ; if(randomclass && deathmatch) { p->class = P_Random()%3; if(p->class == PlayerClass[mthing->type-1]) { p->class = (p->class+1)%3; } PlayerClass[mthing->type-1] = p->class; SB_SetClassData(); } else { p->class = PlayerClass[mthing->type-1]; } switch(p->class) { case PCLASS_FIGHTER: mobj = P_SpawnMobj(x, y, z, MT_PLAYER_FIGHTER); break; case PCLASS_CLERIC: mobj = P_SpawnMobj(x, y, z, MT_PLAYER_CLERIC); break; case PCLASS_MAGE: mobj = P_SpawnMobj(x, y, z, MT_PLAYER_MAGE); break; default: I_Error("P_SpawnPlayer: Unknown class type"); break; } // Set translation table data if(p->class == PCLASS_FIGHTER && (mthing->type == 1 || mthing->type == 3)) { // The first type should be blue, and the third should be the // Fighter's original gold color if(mthing->type == 1) { mobj->flags |= 2<<MF_TRANSSHIFT; } } else if(mthing->type > 1) { // Set color translation bits for player sprites mobj->flags |= (mthing->type-1)<<MF_TRANSSHIFT; } mobj->angle = ANG45 * (mthing->angle/45); mobj->player = p; mobj->health = p->health; p->mo = mobj; p->playerstate = PST_LIVE; p->refire = 0; P_ClearMessage(p); p->damagecount = 0; p->bonuscount = 0; p->poisoncount = 0; p->morphTics = 0; p->extralight = 0; p->fixedcolormap = 0; p->viewheight = VIEWHEIGHT; P_SetupPsprites(p); if(deathmatch) { // Give all keys in death match mode p->keys = 2047; }}//==========================================================================//// P_SpawnMapThing//// The fields of the mapthing should already be in host byte order.////==========================================================================void P_SpawnMapThing(mapthing_t *mthing){ int i; unsigned int spawnMask; mobj_t *mobj; fixed_t x, y, z; static unsigned int classFlags[] = { MTF_FIGHTER, MTF_CLERIC, MTF_MAGE }; // Count deathmatch start positions if(mthing->type == 11) { if(deathmatch_p < &deathmatchstarts[MAXDEATHMATCHSTARTS]) { memcpy(deathmatch_p, mthing, sizeof(*mthing)); deathmatch_p++; } return; } if(mthing->type == PO_ANCHOR_TYPE) { // Polyobj Anchor Pt. return; } else if(mthing->type == PO_SPAWN_TYPE || mthing->type == PO_SPAWNCRUSH_TYPE) { // Polyobj Anchor Pt. po_NumPolyobjs++; return; } // Check for player starts 1 to 4 if(mthing->type <= 4) { playerstarts[mthing->arg1][mthing->type-1] = *mthing; if(!deathmatch && !mthing->arg1) { P_SpawnPlayer(mthing); } return; } // Check for player starts 5 to 8 if(mthing->type >= 9100 && mthing->type <= 9103) { mthing->type = 5+mthing->type-9100; // Translate to 5 - 8 playerstarts[mthing->arg1][mthing->type-1] = *mthing; if(!deathmatch && !mthing->arg1) { P_SpawnPlayer(mthing); } return; } if(mthing->type >= 1400 && mthing->type < 1410) { R_PointInSubsector(mthing->x<<FRACBITS, mthing->y<<FRACBITS)->sector->seqType = mthing->type-1400; return; } // Check current game type with spawn flags if(netgame == false) { spawnMask = MTF_GSINGLE; } else if(deathmatch) { spawnMask = MTF_GDEATHMATCH; } else { spawnMask = MTF_GCOOP; } if(!(mthing->options&spawnMask)) { return; } // Check current skill with spawn flags if(gameskill == sk_baby || gameskill == sk_easy) { spawnMask = MTF_EASY; } else if(gameskill == sk_hard || gameskill == sk_nightmare) { spawnMask = MTF_HARD; } else { spawnMask = MTF_NORMAL; } if(!(mthing->options&spawnMask)) { return; } // Check current character classes with spawn flags if(netgame == false) { // Single player if((mthing->options&classFlags[PlayerClass[0]]) == 0) { // Not for current class return; } } else if(deathmatch == false) { // Cooperative spawnMask = 0; for(i = 0; i < MAXPLAYERS; i++) { if(playeringame[i]) { spawnMask |= classFlags[PlayerClass[i]]; } } if((mthing->options&spawnMask) == 0) { return; } } // Find which type to spawn for(i = 0; i < NUMMOBJTYPES; i++) { if(mthing->type == mobjinfo[i].doomednum) { break; } } if(i == NUMMOBJTYPES) { // Can't find thing type I_Error("P_SpawnMapThing: Unknown type %i at (%i, %i)", mthing->type, mthing->x, mthing->y); } // Don't spawn keys and players in deathmatch if(deathmatch && mobjinfo[i].flags&MF_NOTDMATCH) { return; } // Don't spawn monsters if -nomonsters if(nomonsters && (mobjinfo[i].flags&MF_COUNTKILL)) { return; } x = mthing->x<<FRACBITS; y = mthing->y<<FRACBITS; if(mobjinfo[i].flags&MF_SPAWNCEILING) { z = ONCEILINGZ; } else if(mobjinfo[i].flags2&MF2_SPAWNFLOAT) { z = FLOATRANDZ; } else if(mobjinfo[i].flags2&MF2_FLOATBOB) { z = mthing->height<<FRACBITS; } else { z = ONFLOORZ; } switch(i) { // Special stuff case MT_ZLYNCHED_NOHEART: P_SpawnMobj(x, y, ONFLOORZ, MT_BLOODPOOL); break; default: break; } mobj = P_SpawnMobj(x, y, z, i); if(z == ONFLOORZ) { mobj->z += mthing->height<<FRACBITS; } else if(z == ONCEILINGZ) { mobj->z -= mthing->height<<FRACBITS; } mobj->tid = mthing->tid; mobj->special = mthing->special; mobj->args[0] = mthing->arg1; mobj->args[1] = mthing->arg2; mobj->args[2] = mthing->arg3; mobj->args[3] = mthing->arg4; mobj->args[4] = mthing->arg5; if(mobj->flags2&MF2_FLOATBOB) { // Seed random starting index for bobbing motion mobj->health = P_Random(); mobj->special1 = mthing->height<<FRACBITS; } if(mobj->tics > 0) { mobj->tics = 1+(P_Random()%mobj->tics); }// if(mobj->flags&MF_COUNTITEM)// {// totalitems++;// } if (mobj->flags&MF_COUNTKILL) { // Quantize angle to 45 degree increments mobj->angle = ANG45*(mthing->angle/45); } else { // Scale angle correctly (source is 0..359) mobj->angle = ((mthing->angle<<8)/360)<<24; } if(mthing->options&MTF_AMBUSH) { mobj->flags |= MF_AMBUSH; } if(mthing->options&MTF_DORMANT) { mobj->flags2 |= MF2_DORMANT; if(mobj->type == MT_ICEGUY) { P_SetMobjState(mobj, S_ICEGUY_DORMANT); } mobj->tics = -1; }}//==========================================================================//// P_CreateTIDList////==========================================================================void P_CreateTIDList(void){ int i; mobj_t *mobj; thinker_t *t; i = 0; for(t = thinkercap.next; t != &thinkercap; t = t->next) { // Search all current thinkers if(t->function != P_MobjThinker) { // Not a mobj thinker continue; } mobj = (mobj_t *)t; if(mobj->tid != 0) { // Add to list if(i == MAX_TID_COUNT) { I_Error("P_CreateTIDList: MAX_TID_COUNT (%d) exceeded.", MAX_TID_COUNT); } TIDList[i] = mobj->tid; TIDMobj[i++] = mobj; } } // Add termination marker TIDList[i] = 0;}//==========================================================================//// P_InsertMobjIntoTIDList////==========================================================================void P_InsertMobjIntoTIDList(mobj_t *mobj, int tid){ int i; int index; index = -1; for(i = 0; TIDList[i] != 0; i++) { if(TIDList[i] == -1) { // Found empty slot index = i; break; } } if(index == -1) { // Append required if(i == MAX_TID_COUNT) { I_Error("P_InsertMobjIntoTIDList: MAX_TID_COUNT (%d)" "exceeded.", MAX_TID_COUNT); } index = i; TIDList[index+1] = 0; } mobj->tid = tid; TIDList[index] = tid; TIDMobj[index] = mobj;}//==========================================================================//// P_RemoveMobjFromTIDList////==========================================================================void P_RemoveMobjFromTIDList(mobj_t *mobj){ int i; for(i = 0; TIDList[i] != 0; i++) { if(TIDMobj[i] == mobj) { TIDList[i] = -1; TIDMobj[i] = NULL; mobj->tid = 0; return; } } mobj->tid = 0;}//==========================================================================//// P_FindMobjFromTID////==========================================================================mobj_t *P_FindMobjFromTID(int tid, int *searchPosition){ int i; for(i = *searchPosition+1; TIDList[i] != 0; i++) { if(TIDList[i] == tid) { *searchPosition = i; return TIDMobj[i]; } } *searchPosition = -1; return NULL;}/*=============================================================================== GAME SPAWN FUNCTIONS===============================================================================*///---------------------------------------------------------------------------//// PROC P_SpawnPuff////---------------------------------------------------------------------------extern fixed_t attackrange;void P_SpawnPuff(fixed_t x, fixed_t y, fixed_t z){ mobj_t *puff; z += ((P_Random()-P_Random())<<10); puff = P_SpawnMobj(x, y, z, PuffType); if(linetarget && puff->info->seesound) { // Hit thing sound S_StartSound(puff, puff->info->seesound); } else if(puff->info->attacksound) { S_StartSound(puff, puff->info->attacksound); } switch(PuffType) { case MT_PUNCHPUFF: puff->momz = FRACUNIT; break; case MT_HAMMERPUFF: puff->momz = .8*FRACUNIT; break; default: break; } PuffSpawned = puff;}/*================== P_SpawnBlood=================*//*void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, int damage){ mobj_t *th; z += ((P_Random()-P_Random())<<10); th = P_SpawnMobj (x,y,z, MT_BLOOD); th->momz = FRACUNIT*2; th->tics -= P_Random()&3; if (damage <= 12 && damage >= 9) P_SetMobjState (th,S_BLOOD2); else if (damage < 9) P_SetMobjState (th,S_BLOOD3);}*///---------------------------------------------------------------------------//// PROC P_BloodSplatter////---------------------------------------------------------------------------void P_BloodSplatter(fixed_t x, fixed_t y, fixed_t z, mobj_t *originator){ mobj_t *mo; mo = P_SpawnMobj(x, y, z, MT_BLOODSPLATTER); mo->target = originator; mo->momx = (P_Random()-P_Random())<<10; mo->momy = (P_Random()-P_Random())<<10; mo->momz = 3*FRACUNIT;}//===========================================================================//// P_BloodSplatter2////===========================================================================void P_BloodSplatter2(fixed_t x, fixed_t y, fixed_t z, mobj_t *originator){ mobj_t *mo; mo = P_SpawnMobj(x+((P_Random()-128)<<11), y+((P_Random()-128)<<11), z, MT_AXEBLOOD); mo->target = originator;}//---------------------------------------------------------------------------//// PROC P_RipperBlood////---------------------------------------------------------------------------void P_RipperBlood(mobj_t *mo){ mobj_t *th; fixed_t x, y, z;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -