📄 p_map.c
字号:
// Emacs style mode select -*- C++ -*-//-----------------------------------------------------------------------------//// $Id: p_map.c,v 1.20 2001/04/30 17:19:24 stroggonmeth Exp $//// Copyright (C) 1993-1996 by id Software, Inc.// Portions Copyright (C) 1998-2000 by DooM Legacy Team.//// This program is free software; you can redistribute it and/or// modify it under the terms of the GNU General Public License// as published by the Free Software Foundation; either version 2// of the License, or (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.////// $Log: p_map.c,v $// Revision 1.20 2001/04/30 17:19:24 stroggonmeth// HW fix and misc. changes//// Revision 1.19 2001/04/01 17:35:06 bpereira// no message//// Revision 1.18 2001/03/30 17:12:50 bpereira// no message//// Revision 1.17 2001/03/19 18:52:01 hurdler// lil fix//// Revision 1.16 2001/03/13 22:14:19 stroggonmeth// Long time no commit. 3D floors, FraggleScript, portals, ect.//// Revision 1.15 2001/03/09 21:53:56 metzgermeister// *** empty log message ***//// Revision 1.14 2001/01/25 22:15:43 bpereira// added heretic support//// Revision 1.13 2000/11/02 19:49:35 bpereira// no message//// Revision 1.12 2000/11/02 17:50:08 stroggonmeth// Big 3Dfloors & FraggleScript commit!!//// Revision 1.11 2000/10/21 08:43:30 bpereira// no message//// Revision 1.10 2000/10/01 10:18:17 bpereira// no message//// Revision 1.9 2000/09/28 20:57:16 bpereira// no message//// Revision 1.8 2000/08/31 14:30:55 bpereira// no message//// Revision 1.7 2000/04/23 16:19:52 bpereira// no message//// Revision 1.6 2000/04/16 18:38:07 bpereira// no message//// Revision 1.5 2000/04/15 22:12:57 stroggonmeth// Minor bug fixes//// Revision 1.4 2000/04/11 19:07:24 stroggonmeth// Finished my logs, fixed a crashing bug.//// Revision 1.3 2000/04/04 00:32:47 stroggonmeth// Initial Boom compatability plus few misc changes all around.//// Revision 1.2 2000/02/27 00:42:10 hurdler// fix CR+LF problem//// Revision 1.1.1.1 2000/02/22 20:32:33 hurdler// Initial import into CVS (v1.29 pr3)////// DESCRIPTION:// Movement, collision handling.// Shooting and aiming.////-----------------------------------------------------------------------------#include "doomdef.h"#include "g_game.h"#include "m_bbox.h"#include "m_random.h"#include "p_local.h"#include "p_inter.h"#include "r_state.h"#include "r_main.h"#include "r_sky.h"#include "s_sound.h"#include "r_splats.h" //faB: testing#include "z_zone.h" //SoM: 3/15/2000fixed_t tmbbox[4];mobj_t* tmthing;int tmflags;fixed_t tmx;fixed_t tmy;// If "floatok" true, move would be ok// if within "tmfloorz - tmceilingz".boolean floatok;fixed_t tmfloorz;fixed_t tmceilingz;fixed_t tmdropoffz;mobj_t* tmfloorthing; // the thing corresponding to tmfloorz // or NULL if tmfloorz is from a sector//added:28-02-98: used at P_ThingHeightClip() for moving sectorsfixed_t tmsectorfloorz;fixed_t tmsectorceilingz;// keep track of the line that lowers the ceiling,// so missiles don't explode against sky hack wallsline_t* ceilingline;// set by PIT_CheckLine() for any line that stopped the PIT_CheckLine()// that is, for any line which is 'solid'line_t* blockingline;// keep track of special lines as they are hit,// but don't process them until the move is proven validint *spechit; //SoM: 3/15/2000: Limit removalint numspechit;//SoM: 3/15/2000msecnode_t* sector_list = NULL;//SoM: 3/15/2000static int pe_x; // Pain Elemental position for Lost Soul checksstatic int pe_y; // Pain Elemental position for Lost Soul checksstatic int ls_x; // Lost Soul position for Lost Soul checksstatic int ls_y; // Lost Soul position for Lost Soul checks//// TELEPORT MOVE////// PIT_StompThing//static boolean PIT_StompThing (mobj_t* thing){ fixed_t blockdist; //SoM: 3/15/2000: Move self check to start of routine. // don't clip against self if (thing == tmthing) return true; if (!(thing->flags & MF_SHOOTABLE) ) return true; blockdist = thing->radius + tmthing->radius; if ( abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist ) return true; // didn't hit it // monsters don't stomp things except on boss level if ( gamemode!=heretic && !tmthing->player && gamemap != 30) return false; // Not allowed to stomp things if ( gamemode==heretic && !(tmthing->flags2 & MF2_TELESTOMP)) return (false); P_DamageMobj (thing, tmthing, tmthing, 10000); return true;}//SoM: Not unused. See p_user.c//SoM: 3/15/2000// P_GetMoveFactor() returns the value by which the x,y// movements are multiplied to add to player movement.int P_GetMoveFactor(mobj_t* mo){ int movefactor = ORIG_FRICTION_FACTOR; // If the floor is icy or muddy, it's harder to get moving. This is where // the different friction factors are applied to 'trying to move'. In // p_mobj.c, the friction factors are applied as you coast and slow down. int momentum,friction; if (boomsupport && variable_friction && !(mo->flags & (MF_NOGRAVITY | MF_NOCLIP))) { friction = mo->friction; if (friction == ORIG_FRICTION) // normal floor ; else if (friction > ORIG_FRICTION) // ice { movefactor = mo->movefactor; mo->movefactor = ORIG_FRICTION_FACTOR; // reset } else // sludge { // phares 3/11/98: you start off slowly, then increase as // you get better footing momentum = (P_AproxDistance(mo->momx,mo->momy)); movefactor = mo->movefactor; if (momentum > MORE_FRICTION_MOMENTUM<<2) movefactor <<= 3; else if (momentum > MORE_FRICTION_MOMENTUM<<1) movefactor <<= 2; else if (momentum > MORE_FRICTION_MOMENTUM) movefactor <<= 1; mo->movefactor = ORIG_FRICTION_FACTOR; // reset } } return(movefactor);}//// P_TeleportMove//booleanP_TeleportMove( mobj_t* thing, fixed_t x, fixed_t y ){ int xl; int xh; int yl; int yh; int bx; int by; subsector_t* newsubsec; // kill anything occupying the position tmthing = thing; tmflags = thing->flags; tmx = x; tmy = y; tmbbox[BOXTOP] = y + tmthing->radius; tmbbox[BOXBOTTOM] = y - tmthing->radius; tmbbox[BOXRIGHT] = x + tmthing->radius; tmbbox[BOXLEFT] = x - tmthing->radius; newsubsec = R_PointInSubsector (x,y); ceilingline = NULL; // The base floor/ceiling is from the subsector // that contains the point. // Any contacted lines the step closer together // will adjust them. tmfloorz = tmdropoffz = newsubsec->sector->floorheight; tmceilingz = newsubsec->sector->ceilingheight; validcount++; numspechit = 0; // stomp on any things contacted xl = (tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT; xh = (tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT; yl = (tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT; yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT; for (bx=xl ; bx<=xh ; bx++) for (by=yl ; by<=yh ; by++) if (!P_BlockThingsIterator(bx,by,PIT_StompThing)) return false; // the move is ok, // so link the thing into its new position P_UnsetThingPosition (thing); thing->floorz = tmfloorz; thing->ceilingz = tmceilingz; thing->x = x; thing->y = y; P_SetThingPosition (thing); return true;}// =========================================================================// MOVEMENT ITERATOR FUNCTIONS// =========================================================================static void add_spechit( line_t* ld ){ static int spechit_max = 0; //SoM: 3/15/2000: Boom limit removal. if (numspechit >= spechit_max) { spechit_max = spechit_max ? spechit_max*2 : 16; spechit = (int *)realloc(spechit,sizeof(int)*spechit_max); } spechit[numspechit] = ld - lines; numspechit++;}//// PIT_CheckThing//static boolean PIT_CheckThing (mobj_t* thing){ fixed_t blockdist; boolean solid; int damage; //added:22-02-98: fixed_t topz; fixed_t tmtopz; //SoM: 3/15/2000: Moved to front. // don't clip against self if (thing == tmthing) return true; if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_SHOOTABLE) )) return true;#ifdef CLIENTPREDICTION2 // mobj and spirit of a same player cannot colide if( thing->player && (thing->player->spirit == tmthing || thing->player->mo == tmthing) ) return true;#endif blockdist = thing->radius + tmthing->radius; if ( abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist ) { // didn't hit it return true; } // heretic stuffs if(tmthing->flags2&MF2_PASSMOBJ) { // check if a mobj passed over/under another object if((tmthing->type == MT_IMP || tmthing->type == MT_WIZARD) && (thing->type == MT_IMP || thing->type == MT_WIZARD)) { // don't let imps/wizards fly over other imps/wizards return false; } if(tmthing->z >= thing->z+thing->height && !(thing->flags&MF_SPECIAL)) { return(true); } else if(tmthing->z+tmthing->height < thing->z && !(thing->flags&MF_SPECIAL)) { // under thing return(true); } } // check for skulls slamming into things if (tmflags & MF_SKULLFLY) { damage = ((P_Random()%8)+1)*tmthing->info->damage; P_DamageMobj (thing, tmthing, tmthing, damage); tmthing->flags &= ~MF_SKULLFLY; tmthing->momx = tmthing->momy = tmthing->momz = 0; P_SetMobjState (tmthing, gamemode == heretic ? tmthing->info->seestate : tmthing->info->spawnstate); return false; // stop moving } // missiles can hit other things if (tmthing->flags & MF_MISSILE) { // Check for passing through a ghost (heretic) if ((thing->flags & MF_SHADOW) && (tmthing->flags2 & MF2_THRUGHOST)) return true; // see if it went over / under if (tmthing->z > thing->z + thing->height) return true; // overhead if (tmthing->z+tmthing->height < thing->z) return true; // underneath if (tmthing->target && ( tmthing->target->type == thing->type || (tmthing->target->type == MT_KNIGHT && thing->type == MT_BRUISER)|| (tmthing->target->type == MT_BRUISER && thing->type == MT_KNIGHT) ) ) { // Don't hit same species as originator. if (thing == tmthing->target) return true; if (thing->type != MT_PLAYER) { // Explode, but do no damage. // Let players missile other players. return false; } } if (! (thing->flags & MF_SHOOTABLE) ) { // didn't do any damage return !(thing->flags & MF_SOLID); } // more heretic stuff if (tmthing->flags2 & MF2_RIP) { damage = ((P_Random () & 3) + 2) * tmthing->info->damage; S_StartSound (tmthing, sfx_ripslop); if( P_DamageMobj (thing, tmthing, tmthing->target, damage) ) { if (!(thing->flags & MF_NOBLOOD)) { // Ok to spawn some blood P_SpawnBlood(tmthing->x, tmthing->y, tmthing->z, damage ); //P_RipperBlood (tmthing); } } if (thing->flags2 & MF2_PUSHABLE && !(tmthing->flags2 & MF2_CANNOTPUSH)) { // Push thing thing->momx += tmthing->momx >> 2; thing->momy += tmthing->momy >> 2; } numspechit = 0; return (true); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -