📄 po_man.c
字号:
//**************************************************************************//**//** PO_MAN.C : Heretic 2 : Raven Software, Corp.//**//** $RCSfile: po_man.c,v $//** $Revision: 1.22 $//** $Date: 95/09/28 18:20:56 $//** $Author: cjr $//**//**************************************************************************// HEADER FILES ------------------------------------------------------------#include "h2def.h"#include "p_local.h"#include "r_local.h"// MACROS ------------------------------------------------------------------#define PO_MAXPOLYSEGS 64// TYPES -------------------------------------------------------------------// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------boolean PO_MovePolyobj(int num, int x, int y);boolean PO_RotatePolyobj(int num, angle_t angle);void PO_Init(int lump);// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------static polyobj_t *GetPolyobj(int polyNum);static int GetPolyobjMirror(int poly);static void ThrustMobj(mobj_t *mobj, seg_t *seg, polyobj_t *po);static void UpdateSegBBox(seg_t *seg);static void RotatePt(int an, fixed_t *x, fixed_t *y, fixed_t startSpotX, fixed_t startSpotY);static void UnLinkPolyobj(polyobj_t *po);static void LinkPolyobj(polyobj_t *po);static boolean CheckMobjBlocking(seg_t *seg, polyobj_t *po);static void InitBlockMap(void);static void IterFindPolySegs(int x, int y, seg_t **segList);static void SpawnPolyobj(int index, int tag, boolean crush);static void TranslateToStartSpot(int tag, int originX, int originY);// EXTERNAL DATA DECLARATIONS ----------------------------------------------extern seg_t *segs;// PUBLIC DATA DEFINITIONS -------------------------------------------------polyblock_t **PolyBlockMap;polyobj_t *polyobjs; // list of all poly-objects on the levelint po_NumPolyobjs;// PRIVATE DATA DEFINITIONS ------------------------------------------------static int PolySegCount;static fixed_t PolyStartX;static fixed_t PolyStartY;// CODE --------------------------------------------------------------------// ===== Polyobj Event Code =====//==========================================================================//// T_RotatePoly////==========================================================================void T_RotatePoly(polyevent_t *pe){ int absSpeed; polyobj_t *poly; if(PO_RotatePolyobj(pe->polyobj, pe->speed)) { absSpeed = abs(pe->speed); if(pe->dist == -1) { // perpetual polyobj return; } pe->dist -= absSpeed; if(pe->dist <= 0) { poly = GetPolyobj(pe->polyobj); if(poly->specialdata == pe) { poly->specialdata = NULL; } SN_StopSequence((mobj_t *)&poly->startSpot); P_PolyobjFinished(poly->tag); P_RemoveThinker(&pe->thinker); } if(pe->dist < absSpeed) { pe->speed = pe->dist*(pe->speed < 0 ? -1 : 1); } }}//==========================================================================//// EV_RotatePoly////==========================================================================boolean EV_RotatePoly(line_t *line, byte *args, int direction, boolean overRide){ int mirror; int polyNum; polyevent_t *pe; polyobj_t *poly; polyNum = args[0]; if(poly = GetPolyobj(polyNum)) { if(poly->specialdata && !overRide) { // poly is already moving return false; } } else { I_Error("EV_RotatePoly: Invalid polyobj num: %d\n", polyNum); } pe = Z_Malloc(sizeof(polyevent_t), PU_LEVSPEC, 0); P_AddThinker(&pe->thinker); pe->thinker.function = T_RotatePoly; pe->polyobj = polyNum; if(args[2]) { if(args[2] == 255) { pe->dist = -1; } else { pe->dist = args[2]*(ANGLE_90/64); // Angle } } else { pe->dist = ANGLE_MAX-1; } pe->speed = (args[1]*direction*(ANGLE_90/64))>>3; poly->specialdata = pe; SN_StartSequence((mobj_t *)&poly->startSpot, SEQ_DOOR_STONE+ poly->seqType); while(mirror = GetPolyobjMirror(polyNum)) { poly = GetPolyobj(mirror); if(poly && poly->specialdata && !overRide) { // mirroring poly is already in motion break; } pe = Z_Malloc(sizeof(polyevent_t), PU_LEVSPEC, 0); P_AddThinker(&pe->thinker); pe->thinker.function = T_RotatePoly; poly->specialdata = pe; pe->polyobj = mirror; if(args[2]) { if(args[2] == 255) { pe->dist = -1; } else { pe->dist = args[2]*(ANGLE_90/64); // Angle } } else { pe->dist = ANGLE_MAX-1; } if(poly = GetPolyobj(polyNum)) { poly->specialdata = pe; } else { I_Error("EV_RotatePoly: Invalid polyobj num: %d\n", polyNum); } direction = -direction; pe->speed = (args[1]*direction*(ANGLE_90/64))>>3; polyNum = mirror; SN_StartSequence((mobj_t *)&poly->startSpot, SEQ_DOOR_STONE+ poly->seqType); } return true;}//==========================================================================//// T_MovePoly////==========================================================================void T_MovePoly(polyevent_t *pe){ int absSpeed; polyobj_t *poly; if(PO_MovePolyobj(pe->polyobj, pe->xSpeed, pe->ySpeed)) { absSpeed = abs(pe->speed); pe->dist -= absSpeed; if(pe->dist <= 0) { poly = GetPolyobj(pe->polyobj); if(poly->specialdata == pe) { poly->specialdata = NULL; } SN_StopSequence((mobj_t *)&poly->startSpot); P_PolyobjFinished(poly->tag); P_RemoveThinker(&pe->thinker); } if(pe->dist < absSpeed) { pe->speed = pe->dist*(pe->speed < 0 ? -1 : 1); pe->xSpeed = FixedMul(pe->speed, finecosine[pe->angle]); pe->ySpeed = FixedMul(pe->speed, finesine[pe->angle]); } }}//==========================================================================//// EV_MovePoly////==========================================================================boolean EV_MovePoly(line_t *line, byte *args, boolean timesEight, boolean overRide){ int mirror; int polyNum; polyevent_t *pe; polyobj_t *poly; angle_t an; polyNum = args[0]; if(poly = GetPolyobj(polyNum)) { if(poly->specialdata && !overRide) { // poly is already moving return false; } } else { I_Error("EV_MovePoly: Invalid polyobj num: %d\n", polyNum); } pe = Z_Malloc(sizeof(polyevent_t), PU_LEVSPEC, 0); P_AddThinker(&pe->thinker); pe->thinker.function = T_MovePoly; pe->polyobj = polyNum; if(timesEight) { pe->dist = args[3]*8*FRACUNIT; } else { pe->dist = args[3]*FRACUNIT; // Distance } pe->speed = args[1]*(FRACUNIT/8); poly->specialdata = pe; an = args[2]*(ANGLE_90/64); pe->angle = an>>ANGLETOFINESHIFT; pe->xSpeed = FixedMul(pe->speed, finecosine[pe->angle]); pe->ySpeed = FixedMul(pe->speed, finesine[pe->angle]); SN_StartSequence((mobj_t *)&poly->startSpot, SEQ_DOOR_STONE+ poly->seqType); while(mirror = GetPolyobjMirror(polyNum)) { poly = GetPolyobj(mirror); if(poly && poly->specialdata && !overRide) { // mirroring poly is already in motion break; } pe = Z_Malloc(sizeof(polyevent_t), PU_LEVSPEC, 0); P_AddThinker(&pe->thinker); pe->thinker.function = T_MovePoly; pe->polyobj = mirror; poly->specialdata = pe; if(timesEight) { pe->dist = args[3]*8*FRACUNIT; } else { pe->dist = args[3]*FRACUNIT; // Distance } pe->speed = args[1]*(FRACUNIT/8); an = an+ANGLE_180; // reverse the angle pe->angle = an>>ANGLETOFINESHIFT; pe->xSpeed = FixedMul(pe->speed, finecosine[pe->angle]); pe->ySpeed = FixedMul(pe->speed, finesine[pe->angle]); polyNum = mirror; SN_StartSequence((mobj_t *)&poly->startSpot, SEQ_DOOR_STONE+ poly->seqType); } return true;}//==========================================================================//// T_PolyDoor////==========================================================================void T_PolyDoor(polydoor_t *pd){ int absSpeed; polyobj_t *poly; if(pd->tics) { if(!--pd->tics) { poly = GetPolyobj(pd->polyobj); SN_StartSequence((mobj_t *)&poly->startSpot, SEQ_DOOR_STONE+ poly->seqType); } return; } switch(pd->type) { case PODOOR_SLIDE: if(PO_MovePolyobj(pd->polyobj, pd->xSpeed, pd->ySpeed)) { absSpeed = abs(pd->speed); pd->dist -= absSpeed; if(pd->dist <= 0) { poly = GetPolyobj(pd->polyobj); SN_StopSequence((mobj_t *)&poly->startSpot); if(!pd->close) { pd->dist = pd->totalDist; pd->close = true; pd->tics = pd->waitTics; pd->direction = (ANGLE_MAX>>ANGLETOFINESHIFT)- pd->direction; pd->xSpeed = -pd->xSpeed; pd->ySpeed = -pd->ySpeed; } else { if(poly->specialdata == pd) { poly->specialdata = NULL; } P_PolyobjFinished(poly->tag); P_RemoveThinker(&pd->thinker); } } } else { poly = GetPolyobj(pd->polyobj); if(poly->crush || !pd->close) { // continue moving if the poly is a crusher, or is opening return; } else { // open back up pd->dist = pd->totalDist-pd->dist; pd->direction = (ANGLE_MAX>>ANGLETOFINESHIFT)- pd->direction; pd->xSpeed = -pd->xSpeed; pd->ySpeed = -pd->ySpeed; pd->close = false; SN_StartSequence((mobj_t *)&poly->startSpot, SEQ_DOOR_STONE+poly->seqType); } } break; case PODOOR_SWING: if(PO_RotatePolyobj(pd->polyobj, pd->speed)) { absSpeed = abs(pd->speed); if(pd->dist == -1) { // perpetual polyobj return; } pd->dist -= absSpeed; if(pd->dist <= 0) { poly = GetPolyobj(pd->polyobj); SN_StopSequence((mobj_t *)&poly->startSpot); if(!pd->close) { pd->dist = pd->totalDist; pd->close = true; pd->tics = pd->waitTics; pd->speed = -pd->speed; } else { if(poly->specialdata == pd) { poly->specialdata = NULL; } P_PolyobjFinished(poly->tag); P_RemoveThinker(&pd->thinker); } } } else { poly = GetPolyobj(pd->polyobj); if(poly->crush || !pd->close) { // continue moving if the poly is a crusher, or is opening return; } else { // open back up and rewait pd->dist = pd->totalDist-pd->dist; pd->speed = -pd->speed; pd->close = false; SN_StartSequence((mobj_t *)&poly->startSpot, SEQ_DOOR_STONE+poly->seqType); } } break; default: break; }}//==========================================================================//// EV_OpenPolyDoor////==========================================================================boolean EV_OpenPolyDoor(line_t *line, byte *args, podoortype_t type){ int mirror; int polyNum; polydoor_t *pd; polyobj_t *poly; angle_t an; polyNum = args[0]; if(poly = GetPolyobj(polyNum)) { if(poly->specialdata) { // poly is already moving return false; } } else { I_Error("EV_OpenPolyDoor: Invalid polyobj num: %d\n", polyNum); } pd = Z_Malloc(sizeof(polydoor_t), PU_LEVSPEC, 0); memset(pd, 0, sizeof(polydoor_t)); P_AddThinker(&pd->thinker); pd->thinker.function = T_PolyDoor; pd->type = type; pd->polyobj = polyNum; if(type == PODOOR_SLIDE) { pd->waitTics = args[4]; pd->speed = args[1]*(FRACUNIT/8); pd->totalDist = args[3]*FRACUNIT; // Distance pd->dist = pd->totalDist; an = args[2]*(ANGLE_90/64); pd->direction = an>>ANGLETOFINESHIFT; pd->xSpeed = FixedMul(pd->speed, finecosine[pd->direction]); pd->ySpeed = FixedMul(pd->speed, finesine[pd->direction]); SN_StartSequence((mobj_t *)&poly->startSpot, SEQ_DOOR_STONE+ poly->seqType); } else if(type == PODOOR_SWING) { pd->waitTics = args[3]; pd->direction = 1; // ADD: PODOOR_SWINGL, PODOOR_SWINGR pd->speed = (args[1]*pd->direction*(ANGLE_90/64))>>3; pd->totalDist = args[2]*(ANGLE_90/64); pd->dist = pd->totalDist; SN_StartSequence((mobj_t *)&poly->startSpot, SEQ_DOOR_STONE+ poly->seqType);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -