📄 po_man.c
字号:
} poly->specialdata = pd; while(mirror = GetPolyobjMirror(polyNum)) { poly = GetPolyobj(mirror); if(poly && poly->specialdata) { // mirroring poly is already in motion break; } 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->polyobj = mirror; pd->type = type; poly->specialdata = pd; 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 = an+ANGLE_180; // reverse the angle 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: same as above 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); } polyNum = mirror; } return true;} // ===== Higher Level Poly Interface code =====//==========================================================================//// GetPolyobj////==========================================================================static polyobj_t *GetPolyobj(int polyNum){ int i; for(i = 0; i < po_NumPolyobjs; i++) { if(polyobjs[i].tag == polyNum) { return &polyobjs[i]; } } return NULL;}//==========================================================================//// GetPolyobjMirror////==========================================================================static int GetPolyobjMirror(int poly){ int i; for(i = 0; i < po_NumPolyobjs; i++) { if(polyobjs[i].tag == poly) { return((*polyobjs[i].segs)->linedef->arg2); } } return 0;}//==========================================================================//// ThrustMobj////==========================================================================static void ThrustMobj(mobj_t *mobj, seg_t *seg, polyobj_t *po){ int thrustAngle; int thrustX; int thrustY; polyevent_t *pe; int force; if(!(mobj->flags&MF_SHOOTABLE) && !mobj->player) { return; } thrustAngle = (seg->angle-ANGLE_90)>>ANGLETOFINESHIFT; pe = po->specialdata; if(pe) { if(pe->thinker.function == T_RotatePoly) { force = pe->speed>>8; } else { force = pe->speed>>3; } if(force < FRACUNIT) { force = FRACUNIT; } else if(force > 4*FRACUNIT) { force = 4*FRACUNIT; } } else { force = FRACUNIT; } thrustX = FixedMul(force, finecosine[thrustAngle]); thrustY = FixedMul(force, finesine[thrustAngle]); mobj->momx += thrustX; mobj->momy += thrustY; if(po->crush) { if(!P_CheckPosition(mobj, mobj->x+thrustX, mobj->y+thrustY)) { P_DamageMobj(mobj, NULL, NULL, 3); } }}//==========================================================================//// UpdateSegBBox////==========================================================================static void UpdateSegBBox(seg_t *seg){ line_t *line; line = seg->linedef; if(seg->v1->x < seg->v2->x) { line->bbox[BOXLEFT] = seg->v1->x; line->bbox[BOXRIGHT] = seg->v2->x; } else { line->bbox[BOXLEFT] = seg->v2->x; line->bbox[BOXRIGHT] = seg->v1->x; } if(seg->v1->y < seg->v2->y) { line->bbox[BOXBOTTOM] = seg->v1->y; line->bbox[BOXTOP] = seg->v2->y; } else { line->bbox[BOXBOTTOM] = seg->v2->y; line->bbox[BOXTOP] = seg->v1->y; } // Update the line's slopetype line->dx = line->v2->x - line->v1->x; line->dy = line->v2->y - line->v1->y; if(!line->dx) { line->slopetype = ST_VERTICAL; } else if(!line->dy) { line->slopetype = ST_HORIZONTAL; } else { if(FixedDiv(line->dy, line->dx) > 0) { line->slopetype = ST_POSITIVE; } else { line->slopetype = ST_NEGATIVE; } }}//==========================================================================//// PO_MovePolyobj////==========================================================================boolean PO_MovePolyobj(int num, int x, int y){ int count; seg_t **segList; seg_t **veryTempSeg; polyobj_t *po; vertex_t *prevPts; boolean blocked; if(!(po = GetPolyobj(num))) { I_Error("PO_MovePolyobj: Invalid polyobj number: %d\n", num); } UnLinkPolyobj(po); segList = po->segs; prevPts = po->prevPts; blocked = false; validcount++; for(count = po->numsegs; count; count--, segList++, prevPts++) { if((*segList)->linedef->validcount != validcount) { (*segList)->linedef->bbox[BOXTOP] += y; (*segList)->linedef->bbox[BOXBOTTOM] += y; (*segList)->linedef->bbox[BOXLEFT] += x; (*segList)->linedef->bbox[BOXRIGHT] += x; (*segList)->linedef->validcount = validcount; } for(veryTempSeg = po->segs; veryTempSeg != segList; veryTempSeg++) { if((*veryTempSeg)->v1 == (*segList)->v1) { break; } } if(veryTempSeg == segList) { (*segList)->v1->x += x; (*segList)->v1->y += y; } (*prevPts).x += x; // previous points are unique for each seg (*prevPts).y += y; } segList = po->segs; for(count = po->numsegs; count; count--, segList++) { if(CheckMobjBlocking(*segList, po)) { blocked = true; } } if(blocked) { count = po->numsegs; segList = po->segs; prevPts = po->prevPts; validcount++; while(count--) { if((*segList)->linedef->validcount != validcount) { (*segList)->linedef->bbox[BOXTOP] -= y; (*segList)->linedef->bbox[BOXBOTTOM] -= y; (*segList)->linedef->bbox[BOXLEFT] -= x; (*segList)->linedef->bbox[BOXRIGHT] -= x; (*segList)->linedef->validcount = validcount; } for(veryTempSeg = po->segs; veryTempSeg != segList; veryTempSeg++) { if((*veryTempSeg)->v1 == (*segList)->v1) { break; } } if(veryTempSeg == segList) { (*segList)->v1->x -= x; (*segList)->v1->y -= y; } (*prevPts).x -= x; (*prevPts).y -= y; segList++; prevPts++; } LinkPolyobj(po); return false; } po->startSpot.x += x; po->startSpot.y += y; LinkPolyobj(po); return true;}//==========================================================================//// RotatePt////==========================================================================static void RotatePt(int an, fixed_t *x, fixed_t *y, fixed_t startSpotX, fixed_t startSpotY){ fixed_t trx, try; fixed_t gxt, gyt; trx = *x; try = *y; gxt = FixedMul(trx, finecosine[an]); gyt = FixedMul(try, finesine[an]); *x = (gxt-gyt)+startSpotX; gxt = FixedMul(trx, finesine[an]); gyt = FixedMul(try, finecosine[an]); *y = (gyt+gxt)+startSpotY;}//==========================================================================//// PO_RotatePolyobj////==========================================================================boolean PO_RotatePolyobj(int num, angle_t angle){ int count; seg_t **segList; vertex_t *originalPts; vertex_t *prevPts; int an; polyobj_t *po; boolean blocked; if(!(po = GetPolyobj(num))) { I_Error("PO_RotatePolyobj: Invalid polyobj number: %d\n", num); } an = (po->angle+angle)>>ANGLETOFINESHIFT; UnLinkPolyobj(po); segList = po->segs; originalPts = po->originalPts; prevPts = po->prevPts; for(count = po->numsegs; count; count--, segList++, originalPts++, prevPts++) { prevPts->x = (*segList)->v1->x; prevPts->y = (*segList)->v1->y; (*segList)->v1->x = originalPts->x; (*segList)->v1->y = originalPts->y; RotatePt(an, &(*segList)->v1->x, &(*segList)->v1->y, po->startSpot.x, po->startSpot.y); } segList = po->segs; blocked = false; validcount++; for(count = po->numsegs; count; count--, segList++) { if(CheckMobjBlocking(*segList, po)) { blocked = true; } if((*segList)->linedef->validcount != validcount) { UpdateSegBBox(*segList); (*segList)->linedef->validcount = validcount; } (*segList)->angle += angle; } if(blocked) { segList = po->segs; prevPts = po->prevPts; for(count = po->numsegs; count; count--, segList++, prevPts++) { (*segList)->v1->x = prevPts->x; (*segList)->v1->y = prevPts->y; } segList = po->segs; validcount++; for(count = po->numsegs; count; count--, segList++, prevPts++) { if((*segList)->linedef->validcount != validcount) { UpdateSegBBox(*segList); (*segList)->linedef->validcount = validcount; } (*segList)->angle -= angle; } LinkPolyobj(po); return false; } po->angle += angle; LinkPolyobj(po); return true;}//==========================================================================//// UnLinkPolyobj////==========================================================================static void UnLinkPolyobj(polyobj_t *po){ polyblock_t *link; int i, j; int index; // remove the polyobj from each blockmap section for(j = po->bbox[BOXBOTTOM]; j <= po->bbox[BOXTOP]; j++) { index = j*bmapwidth; for(i = po->bbox[BOXLEFT]; i <= po->bbox[BOXRIGHT]; i++) { if(i >= 0 && i < bmapwidth && j >= 0 && j < bmapheight) { link = PolyBlockMap[index+i]; while(link != NULL && link->polyobj != po) { link = link->next; } if(link == NULL) { // polyobj not located in the link cell continue; } link->polyobj = NULL; } } }}//==========================================================================//// LinkPolyobj////==========================================================================static void LinkPolyobj(polyobj_t *po){ int leftX, rightX; int topY, bottomY; seg_t **tempSeg; polyblock_t **link; polyblock_t *tempLink; int i, j; // calculate the polyobj bbox tempSeg = po->segs; rightX = leftX = (*tempSeg)->v1->x; topY = bottomY = (*tempSeg)->v1->y; for(i = 0; i < po->numsegs; i++, tempSeg++) { if((*tempSeg)->v1->x > rightX) { rightX = (*tempSeg)->v1->x; } if((*tempSeg)->v1->x < leftX) { leftX = (*tempSeg)->v1->x; } if((*tempSeg)->v1->y > topY) { topY = (*tempSeg)->v1->y; } if((*tempSeg)->v1->y < bottomY) { bottomY = (*tempSeg)->v1->y; } } po->bbox[BOXRIGHT] = (rightX-bmaporgx)>>MAPBLOCKSHIFT; po->bbox[BOXLEFT] = (leftX-bmaporgx)>>MAPBLOCKSHIFT; po->bbox[BOXTOP] = (topY-bmaporgy)>>MAPBLOCKSHIFT; po->bbox[BOXBOTTOM] = (bottomY-bmaporgy)>>MAPBLOCKSHIFT; // add the polyobj to each blockmap section for(j = po->bbox[BOXBOTTOM]*bmapwidth; j <= po->bbox[BOXTOP]*bmapwidth; j += bmapwidth) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -