📄 p_mobj.c
字号:
switch(PuffType) { case MT_BEAKPUFF: case MT_STAFFPUFF: puff->momz = FRACUNIT; break; case MT_GAUNTLETPUFF1: case MT_GAUNTLETPUFF2: puff->momz = .8*FRACUNIT; default: break; } } else { puff = P_SpawnMobj (x,y,z, MT_PUFF); puff->momz = FRACUNIT; puff->tics -= P_Random()&3; if (puff->tics < 1) puff->tics = 1; // don't make punches spark on the wall if (attackrange == MELEERANGE) P_SetMobjState (puff, S_PUFF3); }}// --------------------------------------------------------------------------// P_SpawnBlood// --------------------------------------------------------------------------static mobj_t* bloodthing;static fixed_t bloodspawnpointx,bloodspawnpointy;#ifdef WALLSPLATSboolean PTR_BloodTraverse (intercept_t* in){ line_t* li; divline_t divl; fixed_t frac; fixed_t z; if (in->isaline) { li = in->d.line; z = bloodthing->z + (P_SignedRandom()<<(FRACBITS-3)); if ( !(li->flags & ML_TWOSIDED) ) goto hitline; P_LineOpening (li); // hit lower texture ? if (li->frontsector->floorheight != li->backsector->floorheight) { if( openbottom>z ) goto hitline; } // hit upper texture ? if (li->frontsector->ceilingheight != li->backsector->ceilingheight) { if( opentop<z ) goto hitline; } // else don't hit return true;hitline: P_MakeDivline (li, &divl); frac = P_InterceptVector (&divl, &trace); if( gamemode == heretic ) R_AddWallSplat (li, P_PointOnLineSide(bloodspawnpointx,bloodspawnpointy,li),"BLODC0", z, frac, SPLATDRAWMODE_TRANS); else R_AddWallSplat (li, P_PointOnLineSide(bloodspawnpointx,bloodspawnpointy,li),"BLUDC0", z, frac, SPLATDRAWMODE_TRANS); return false; } //continue return true;}#endif// P_SpawnBloodSplats// the new SpawnBlood : this one first calls P_SpawnBlood for the usual blood sprites// then spawns blood splats around on walls//void P_SpawnBloodSplats ( fixed_t x, fixed_t y, fixed_t z, int damage, fixed_t momx, fixed_t momy){#ifdef WALLSPLATS//static int counter =0; fixed_t x2,y2; angle_t angle, anglesplat; int distance; angle_t anglemul=1; int numsplats; int i;#endif // spawn the usual falling blood sprites at location P_SpawnBlood (x,y,z,damage); //CONS_Printf ("spawned blood counter %d\n", counter++); if( demoversion<129) return;#ifdef WALLSPLATS // traverse all linedefs and mobjs from the blockmap containing t1, // to the blockmap containing the dest. point. // Call the function for each mobj/line on the way, // starting with the mobj/linedef at the shortest distance... if(!momx && !momy) { // from inside angle=0; anglemul=2; } else { // get direction of damage x2 = x + momx; y2 = y + momy; angle = R_PointToAngle2 (x,y,x2,y2); } distance = damage * 6; numsplats = damage / 3+1; // BFG is funy without this check if( numsplats > 20 ) numsplats = 20; //CONS_Printf ("spawning %d bloodsplats at distance of %d\n", numsplats, distance); //CONS_Printf ("damage %d\n", damage); bloodspawnpointx = x; bloodspawnpointy = y; //uses 'bloodthing' set by P_SpawnBlood() for (i=0; i<numsplats; i++) { // find random angle between 0-180deg centered on damage angle anglesplat = angle + (((P_Random() - 128) * FINEANGLES/512*anglemul)<<ANGLETOFINESHIFT); x2 = x + distance*finecosine[anglesplat>>ANGLETOFINESHIFT]; y2 = y + distance*finesine[anglesplat>>ANGLETOFINESHIFT]; P_PathTraverse ( x, y, x2, y2, PT_ADDLINES, PTR_BloodTraverse ); }#endif#ifdef FLOORSPLATS // add a test floor splat R_AddFloorSplat (bloodthing->subsector, "STEP2", x, y, bloodthing->floorz, SPLATDRAWMODE_SHADE);#endif}// P_SpawnBlood// spawn a blood sprite with falling z movement, at location// the duration and first sprite frame depends on the damage level// the more damage, the longer is the sprite animationvoid P_SpawnBlood ( fixed_t x, fixed_t y, fixed_t z, int damage ){ mobj_t* th; z += P_SignedRandom()<<10; th = P_SpawnMobj (x,y,z, MT_BLOOD); if(demoversion>=128) { th->momx = P_SignedRandom()<<12; //faB:19jan99 th->momy = P_SignedRandom()<<12; //faB:19jan99 } th->momz = FRACUNIT*2; th->tics -= P_Random()&3; if (th->tics < 1) th->tics = 1; if (damage <= 12 && damage >= 9) P_SetMobjState (th,S_BLOOD2); else if (damage < 9) P_SetMobjState (th,S_BLOOD3); bloodthing = th;}//---------------------------------------------------------------------------//// FUNC P_HitFloor////---------------------------------------------------------------------------int P_HitFloor(mobj_t *thing){ mobj_t *mo; int floortype; if(thing->floorz != thing->subsector->sector->floorheight) { // don't splash if landing on the edge above water/lava/etc.... return(FLOOR_SOLID); } floortype = P_GetThingFloorType(thing); if( gamemode == heretic ) { if( thing->type!=MT_BLOOD ) { switch( floortype ) { case FLOOR_WATER: P_SpawnMobj(thing->x, thing->y, ONFLOORZ, MT_SPLASHBASE); mo = P_SpawnMobj(thing->x, thing->y, ONFLOORZ, MT_HSPLASH); mo->target = thing; mo->momx = P_SignedRandom()<<8; mo->momy = P_SignedRandom()<<8; mo->momz = 2*FRACUNIT+(P_Random()<<8); S_StartSound(mo, sfx_gloop); break; case FLOOR_LAVA: P_SpawnMobj(thing->x, thing->y, ONFLOORZ, MT_LAVASPLASH); mo = P_SpawnMobj(thing->x, thing->y, ONFLOORZ, MT_LAVASMOKE); mo->momz = FRACUNIT+(P_Random()<<7); S_StartSound(mo, sfx_burn); break; case FLOOR_SLUDGE: P_SpawnMobj(thing->x, thing->y, ONFLOORZ, MT_SLUDGESPLASH); mo = P_SpawnMobj(thing->x, thing->y, ONFLOORZ, MT_SLUDGECHUNK); mo->target = thing; mo->momx = P_SignedRandom()<<8; mo->momy = P_SignedRandom()<<8; mo->momz = FRACUNIT+(P_Random()<<8); break; } } return floortype; } else if( floortype == FLOOR_WATER ) P_SpawnSplash(thing,thing->floorz); // do not down the viewpoint return(FLOOR_SOLID); }//// P_CheckMissileSpawn// Moves the missile forward a bit// and possibly explodes it right there.//boolean P_CheckMissileSpawn (mobj_t* th){ if( gamemode != heretic ) { th->tics -= P_Random()&3; if (th->tics < 1) th->tics = 1; } // move a little forward so an angle can // be computed if it immediately explodes th->x += (th->momx>>1); th->y += (th->momy>>1); th->z += (th->momz>>1); if (!P_TryMove (th, th->x, th->y, false)) { P_ExplodeMissile (th); return false; } return true;}//// P_SpawnMissile//mobj_t* P_SpawnMissile ( mobj_t* source, mobj_t* dest, mobjtype_t type ){ mobj_t* th; angle_t an; int dist; fixed_t z;#ifdef PARANOIA if(!source) I_Error("P_SpawnMissile : no source"); if(!dest) I_Error("P_SpawnMissile : no dest");#endif switch(type) { case MT_MNTRFX1: // Minotaur swing attack missile z = source->z+40*FRACUNIT; break; case MT_MNTRFX2: // Minotaur floor fire missile z = ONFLOORZ; break; case MT_SRCRFX1: // Sorcerer Demon fireball z = source->z+48*FRACUNIT; break; case MT_KNIGHTAXE: // Knight normal axe case MT_REDAXE: // Knight red power axe z = source->z+36*FRACUNIT; break; default: z = source->z+32*FRACUNIT; break; } if(source->flags2&MF2_FEETARECLIPPED) z -= FOOTCLIPSIZE; th = P_SpawnMobj (source->x, source->y, z, type); if (th->info->seesound) S_StartSound (th, th->info->seesound); th->target = source; // where it came from an = R_PointToAngle2 (source->x, source->y, dest->x, dest->y); // fuzzy player if (dest->flags & MF_SHADOW) { if( gamemode == heretic ) an += P_SignedRandom()<<21; else an += P_SignedRandom()<<20; } th->angle = an; an >>= ANGLETOFINESHIFT; th->momx = FixedMul (th->info->speed, finecosine[an]); th->momy = FixedMul (th->info->speed, finesine[an]); dist = P_AproxDistance (dest->x - source->x, dest->y - source->y); dist = dist / th->info->speed; if (dist < 1) dist = 1; th->momz = (dest->z - source->z) / dist; dist = P_CheckMissileSpawn (th); if( demoversion <131 ) return th; else return dist ? th : NULL;}//// P_SpawnPlayerMissile// Tries to aim at a nearby monster//mobj_t *P_SPMAngle ( mobj_t* source, mobjtype_t type, angle_t angle ){ mobj_t* th; angle_t an; fixed_t x; fixed_t y; fixed_t z; fixed_t slope=0; // angle at which you fire, is player angle an = angle; //added:16-02-98: autoaim is now a toggle if (source->player->autoaim_toggle && cv_allowautoaim.value) { // see which target is to be aimed at slope = P_AimLineAttack (source, an, 16*64*FRACUNIT); if (!linetarget) { an += 1<<26; slope = P_AimLineAttack (source, an, 16*64*FRACUNIT); if (!linetarget) { an -= 2<<26; slope = P_AimLineAttack (source, an, 16*64*FRACUNIT); } if (!linetarget) { an = angle; slope = 0; } } } //added:18-02-98: if not autoaim, or if the autoaim didnt aim something, // use the mouseaiming if (!(source->player->autoaim_toggle && cv_allowautoaim.value) || (!linetarget && demoversion>111)) { if(demoversion>=128) slope = AIMINGTOSLOPE(source->player->aiming); else slope = (source->player->aiming<<FRACBITS)/160; } x = source->x; y = source->y; z = source->z + 4*8*FRACUNIT; if(source->flags2&MF2_FEETARECLIPPED) z -= FOOTCLIPSIZE; th = P_SpawnMobj (x,y,z, type); if (th->info->seesound) S_StartSound (th, th->info->seesound); th->target = source; th->angle = an; th->momx = FixedMul( th->info->speed, finecosine[an>>ANGLETOFINESHIFT]); th->momy = FixedMul( th->info->speed, finesine[an>>ANGLETOFINESHIFT]); if( demoversion>=128 ) { // 1.28 fix, allow full aiming must be much precise th->momx = FixedMul(th->momx,finecosine[source->player->aiming>>ANGLETOFINESHIFT]); th->momy = FixedMul(th->momy,finecosine[source->player->aiming>>ANGLETOFINESHIFT]); } th->momz = FixedMul( th->info->speed, slope); if(th->type == MT_BLASTERFX1) { // Ultra-fast ripper spawning missile th->x += (th->momx>>3)-(th->momx>>1); th->y += (th->momy>>3)-(th->momy>>1); th->z += (th->momz>>3)-(th->momz>>1); } slope = P_CheckMissileSpawn (th); if( demoversion<131 ) return th; else return slope ? th : NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -