int EV_DoFloorAndCeiling(line_t *line, byte *args, boolean raise) { boolean floor, ceiling; int secnum; sector_t *sec; if(raise) { floor = EV_DoFloor(line, args, FLEV_RAISEFLOORBYVALUE); secnum = -1; while((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0) { sec = §ors[secnum]; sec->specialdata = NULL; } ceiling = EV_DoCeiling(line, args, CLEV_RAISEBYVALUE); } else { floor = EV_DoFloor(line, args, FLEV_LOWERFLOORBYVALUE); secnum = -1; while ((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0) { sec = §ors[secnum]; sec->specialdata = NULL; } ceiling = EV_DoCeiling(line, args, CLEV_LOWERBYVALUE); } return (floor|ceiling); }
// restore the players position -- sector must be the same shape void P_RestorePlayerPosition(void) { sector_t *sec; int secnum; // we always save and restore the psprites memcpy(save_player->psprites, save_psprites, sizeof(save_player->psprites)); // restore player position from x,y offset if(save_sectag == -1) return; // no sector relativeness if((secnum = P_FindSectorFromTag(save_sectag, -1)) < 0) { // invalid: sector not found return; } sec = §ors[secnum]; // restore position P_UnsetThingPosition(save_player->mo); save_player->mo->x = sec->soundorg.x + save_xoffset; save_player->mo->y = sec->soundorg.y + save_yoffset; // restore various other things save_player->mo->angle = save_mobj.angle; save_player->mo->momx = save_mobj.momx; // keep momentum save_player->mo->momy = save_mobj.momy; P_SetThingPosition(save_player->mo); }
// save a player's position relative to a particular sector void P_SavePlayerPosition(player_t *player, int sectag) { sector_t *sec; int secnum; save_player = player; // save psprites whatever happens memcpy(save_psprites, player->psprites, sizeof(player->psprites)); // save sector x,y offset save_sectag = sectag; if((secnum = P_FindSectorFromTag(sectag, -1)) < 0) { // invalid: sector not found save_sectag = -1; return; } sec = §ors[secnum]; // use soundorg x and y as 'centre' of sector save_xoffset = player->mo->x - sec->soundorg.x; save_yoffset = player->mo->y - sec->soundorg.y; // save mobj so we can restore various bits of data // haleyjd 02/04/13: not legit for C++; must replace if rehabilitated #if 0 memcpy(&save_mobj, player->mo, sizeof(Mobj)); #endif }
// killough 10/98: // // EV_LightTurnOnPartway() // // Turn sectors tagged to line lights on to specified or max neighbor level // // Passed the activating line's tag, and a light level fraction between // 0 and 1. Sets the light to min on 0, max on 1, and interpolates in- // between. Used for doors with gradual lighting effects. // // haleyjd 02/28/05: changed to take a tag instead of a line. // // Returns true // int EV_LightTurnOnPartway(int tag, fixed_t level) { int i; if(level < 0) // clip at extremes level = 0; if(level > FRACUNIT) level = FRACUNIT; // search all sectors for ones with same tag as activating line for(i = -1; (i = P_FindSectorFromTag(tag, i)) >= 0;) { sector_t *temp, *sector = sectors + i; int j, bright = 0, min = sector->lightlevel; for(j = 0; j < sector->linecount; ++j) { if((temp = getNextSector(sector->lines[j], sector))) { if(temp->lightlevel > bright) bright = temp->lightlevel; if(temp->lightlevel < min) min = temp->lightlevel; } } sector->lightlevel = // Set level in-between extremes (level * bright + (FRACUNIT - level) * min) >> FRACBITS; } return 1; }
// // TURN LINE'S TAG LIGHTS ON // [RH] Takes a tag instead of a line // void EV_LightTurnOn (int tag, int bright) { int secnum = -1; // [RH] Don't do a linear search while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) { sector_t *sector = sectors + secnum; // bright = -1 means to search ([RH] Not 0) // for highest light level // surrounding sector if (bright < 0) { int j; bright = 0; for (j = 0; j < sector->linecount; j++) { sector_t *temp = getNextSector (sector->lines[j], sector); if (!temp) continue; if (temp->lightlevel > bright) bright = temp->lightlevel; } } sector->lightlevel = CLIPLIGHT(bright); } }
BOOL EV_DoPillar (DPillar::EPillar type, int tag, fixed_t speed, fixed_t height, fixed_t height2, bool crush) { BOOL rtn = false; int secnum = -1; while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) { sector_t *sec = §ors[secnum]; fixed_t floorheight = P_FloorHeight(sec); fixed_t ceilingheight = P_CeilingHeight(sec); if (sec->floordata || sec->ceilingdata) continue; if (type == DPillar::pillarBuild && floorheight == ceilingheight) continue; if (type == DPillar::pillarOpen && floorheight != ceilingheight) continue; rtn = true; new DPillar (sec, type, speed, height, height2, crush); P_AddMovingCeiling(sec); } return rtn; }
int EV_BuildPillar(line_t *line, byte *args, boolean crush) { int secnum; sector_t *sec; pillar_t *pillar; int newHeight; int rtn; rtn = 0; secnum = -1; while((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0) { sec = §ors[secnum]; if(sec->specialdata) continue; // already moving if(sec->floorheight == sec->ceilingheight) { // pillar is already closed continue; } rtn = 1; if(!args[2]) { newHeight = sec->floorheight+ ((sec->ceilingheight-sec->floorheight)/2); } else { newHeight = sec->floorheight+(args[2]<<FRACBITS); } pillar = Z_Malloc(sizeof(*pillar), PU_LEVSPEC, 0); sec->specialdata = pillar; P_AddThinker(&pillar->thinker); pillar->thinker.function = T_BuildPillar; pillar->sector = sec; if(!args[2]) { pillar->ceilingSpeed = pillar->floorSpeed = args[1]*(FRACUNIT/8); } else if(newHeight-sec->floorheight > sec->ceilingheight-newHeight) { pillar->floorSpeed = args[1]*(FRACUNIT/8); pillar->ceilingSpeed = FixedMul(sec->ceilingheight-newHeight, FixedDiv(pillar->floorSpeed, newHeight-sec->floorheight)); } else { pillar->ceilingSpeed = args[1]*(FRACUNIT/8); pillar->floorSpeed = FixedMul(newHeight-sec->floorheight, FixedDiv(pillar->ceilingSpeed, sec->ceilingheight-newHeight)); } pillar->floordest = newHeight; pillar->ceilingdest = newHeight; pillar->direction = 1; pillar->crush = crush*args[3]; SN_StartSequence((mobj_t *)&pillar->sector->soundorg, SEQ_PLATFORM+pillar->sector->seqType); } return rtn; }
boolean EV_StartFloorWaggle(int tag, int height, int speed, int offset, int timer) { int sectorIndex; sector_t *sector; floorWaggle_t *waggle; boolean retCode; retCode = false; sectorIndex = -1; while((sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0) { sector = §ors[sectorIndex]; if(sector->specialdata) { // Already busy with another thinker continue; } retCode = true; waggle = Z_Malloc(sizeof(*waggle), PU_LEVSPEC, 0); sector->specialdata = waggle; waggle->thinker.function = T_FloorWaggle; waggle->sector = sector; waggle->originalHeight = sector->floorheight; waggle->accumulator = offset*FRACUNIT; waggle->accDelta = speed<<10; waggle->scale = 0; waggle->targetScale = height<<10; waggle->scaleDelta = waggle->targetScale /(35+((3*35)*height)/255); waggle->ticker = timer ? timer*35 : -1; waggle->state = WGLSTATE_EXPAND; P_AddThinker(&waggle->thinker); } return retCode; }
void EV_TurnTagLightsOff (int tag) { int i; int secnum; // [RH] Don't do a linear search for (secnum = -1; (secnum = P_FindSectorFromTag (tag, secnum)) >= 0; ) { sector_t *sector = sectors + secnum; int min = sector->lightlevel; for (i = 0; i < sector->linecount; i++) { sector_t *tsec = getNextSector (sector->lines[i],sector); if (!tsec) continue; if (tsec->lightlevel < min) min = tsec->lightlevel; } sector->SetLightLevel(min); // [BC] Flag the sector as having its light level altered. That way, when clients // connect, we can tell them about the updated light level. sector->bLightChange = true; // [BC] If we're the server, tell clients about the light level change. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_SetSectorLightLevel( secnum ); } }
int P_DoSectorLightChange(line_t* line, short tag) { int j = 0; int ptr1 = 0; int ptr2 = 0; sector_t* sec1; sector_t* sec2; int secnum; int rtn; secnum = P_FindSectorFromTag(tag); if(secnum == -1) { return 0; } sec2 = §ors[secnum]; secnum = -1; rtn = 0; while((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) { sec1 = §ors[secnum]; rtn = 1; for(j = 0; j < 5; j++) { ptr1 = (sec1->colors[j]); ptr2 = (sec2->colors[j]); P_UpdateLightThinker(&lights[ptr1], &lights[ptr2]); } } return 1; }
// // ACS_funcSectorDamage // static void ACS_funcSectorDamage(ACS_FUNCARG) { int32_t tag = args[0]; int32_t damage = args[1]; int mod = E_DamageTypeNumForName(ACSVM::GetString(args[2])); uint32_t flags = args[4]; int secnum = -1; sector_t *sector; while((secnum = P_FindSectorFromTag(tag, secnum)) >= 0) { sector = §ors[secnum]; for(Mobj *mo = sector->thinglist; mo; mo = mo->snext) { if(mo->player && !(flags & SECDAM_PLAYERS)) continue; if(!mo->player && !(flags & SECDAM_NONPLAYERS)) continue; if(mo->z != mo->floorz && !(flags & SECDAM_IN_AIR)) continue; P_DamageMobj(mo, NULL, NULL, damage, mod); } } }
void EV_LightTurnOnPartway (int tag, fixed_t frac) { int i; frac = clamp<fixed_t> (frac, 0, FRACUNIT); // Search all sectors for ones with same tag as activating line i = -1; while ((i = P_FindSectorFromTag (tag, i)) >= 0) { sector_t *temp, *sector = sectors + i; int j, bright = 0, min = sector->lightlevel; for (j = 0; j < sector->linecount; ++j) { if ((temp = getNextSector (sector->lines[j], sector)) != NULL) { if (temp->lightlevel > bright) { bright = temp->lightlevel; } if (temp->lightlevel < min) { min = temp->lightlevel; } } } sector->SetLightLevel(DMulScale16 (frac, bright, FRACUNIT-frac, min)); } }
void EV_StartLightGlowing (int tag, int upper, int lower, int tics) { int secnum; // If tics is non-positive, then we can't really do anything. if (tics <= 0) { return; } if (upper < lower) { int temp = upper; upper = lower; lower = temp; } secnum = -1; while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0) { sector_t *sec = §ors[secnum]; if (sec->lightingdata) continue; new DGlow2 (sec, upper, lower, tics, false); } }
// // ACS_thingCountSector // static int32_t ACS_thingCountSector(int32_t tag, mobjtype_t type, int32_t tid) { sector_t *sector; int count = 0; int secnum = -1; while((secnum = P_FindSectorFromTag(tag, secnum)) >= 0) { sector = §ors[secnum]; for(Mobj *mo = sector->thinglist; mo; mo = mo->snext) { if((type == 0 || mo->type == type) && (tid == 0 || mo->tid == tid)) { // don't count killable things that are dead if(((mo->flags & MF_COUNTKILL) || (mo->flags3 & MF3_KILLABLE)) && mo->health <= 0) continue; ++count; } } } return count; }
void EV_StartLightFading (int tag, int value, int tics) { int secnum; secnum = -1; while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0) { sector_t *sec = §ors[secnum]; if (sec->lightingdata) continue; if (tics <= 0) { sec->SetLightLevel(value); } else { // No need to fade if lightlevel is already at desired value. if (sec->lightlevel == value) continue; new DGlow2 (sec, sec->lightlevel, value, tics, true); } } }
// // [RH] New function to adjust tagged sectors' light levels // by a relative amount. Light levels are clipped to // within the range 0-255 inclusive. // void EV_LightChange (int tag, int value) { int secnum = -1; while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) { int newlight = sectors[secnum].lightlevel + value; sectors[secnum].lightlevel = CLIPLIGHT(newlight); } }
void EV_LightChange (int tag, int value) { int secnum = -1; while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) { sectors[secnum].SetLightLevel(sectors[secnum].lightlevel + value); } }
void EV_StartLightFlickering (int tag, int upper, int lower) { int secnum; secnum = -1; while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0) { new DFlicker (§ors[secnum], upper, lower); } }
// // EV_GlowLight // // haleyjd: // Parameterized glow effect. Uses the fading thinker, but sets it up to // perpetually fade between two different light levels. The glow always starts // by fading the sector toward the lower light level, whether that requires // fading up or down. // int EV_GlowLight(line_t *line, int tag, int maxval, int minval, int speed) { int i, rtn = 0; LightFadeThinker *lf; bool backside = false; // speed <= 0? hell no. if(speed <= 0 || maxval == minval) return rtn; // ensure min and max have proper relationship if(maxval < minval) { int temp = maxval; maxval = minval; minval = temp; } if(line && tag == 0) { if(!line->backsector) return rtn; i = line->backsector - sectors; backside = true; goto dobackside; } // search all sectors for ones with tag for(i = -1; (i = P_FindSectorFromTag(tag, i)) >= 0;) { dobackside: rtn = 1; lf = new LightFadeThinker; lf->addThinker(); lf->sector = §ors[i]; lf->glowmin = minval * FRACUNIT; lf->glowmax = maxval * FRACUNIT; lf->glowspeed = speed; // start out fading to min level lf->destlevel = lf->glowmin; // dest. light level lf->lightlevel = lf->sector->lightlevel * FRACUNIT; // curr. light level lf->step = (lf->destlevel - lf->lightlevel) / speed; // delta per frame lf->type = fade_glow; if(backside) return rtn; } return rtn; }
// // P_ChangeCeilingTex // // Changes the ceiling flat of all tagged sectors. // void P_ChangeCeilingTex(const char *name, int tag) { int flatnum; int secnum = -1; if((flatnum = R_CheckForFlat(name)) == -1) return; while((secnum = P_FindSectorFromTag(tag, secnum)) >= 0) P_SetSectorCeilingPic(§ors[secnum], flatnum); }
// // ACS_funcGetSectorFloorZ // static void ACS_funcGetSectorFloorZ(ACS_FUNCARG) { int secnum = P_FindSectorFromTag(args[0], -1); if(secnum >= 0) { // TODO/FIXME: sloped sectors *retn++ = sectors[secnum].floorheight; } else *retn++ = 0; }
int EV_DoDoor(line_t *line, byte *args, vldoor_e type) { int secnum; int retcode; sector_t *sec; vldoor_t *door; fixed_t speed; speed = args[1]*FRACUNIT/8; secnum = -1; retcode = 0; while((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0) { sec = §ors[secnum]; if(sec->specialdata) { continue; } // Add new door thinker retcode = 1; door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0); P_AddThinker(&door->thinker); sec->specialdata = door; door->thinker.function = T_VerticalDoor; door->sector = sec; switch(type) { case DREV_CLOSE: door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->direction = -1; break; case DREV_CLOSE30THENOPEN: door->topheight = sec->ceilingheight; door->direction = -1; break; case DREV_NORMAL: case DREV_OPEN: door->direction = 1; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; break; default: break; } door->type = type; door->speed = speed; door->topwait = args[2]; // line->arg3 SN_StartSequence((mobj_t *)&door->sector->soundorg, SEQ_DOOR_STONE+door->sector->seqType); } return(retcode); }
static boolean TagBusy(int tag) { int sectorIndex; sectorIndex = -1; while ((sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0) { if (sectors[sectorIndex].specialdata) { return true; } } return false; }
void EV_StartLightStrobing (int tag, int utics, int ltics) { int secnum; secnum = -1; while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0) { sector_t *sec = §ors[secnum]; if (sec->lightingdata) continue; new DStrobe (sec, utics, ltics, false); } }
int EV_BuildStairs(line_t *line, byte *args, int direction, stairs_e stairsType) { int secnum; int height; int delay; int resetDelay; sector_t *sec; sector_t *qSec; int type; // Set global stairs variables TextureChange = 0; Direction = direction; StepDelta = Direction*(args[2]*FRACUNIT); Speed = args[1]*(FRACUNIT/8); resetDelay = args[4]; delay = args[3]; if(stairsType == STAIRS_PHASED) { StartDelayDelta = args[3]; StartDelay = StartDelayDelta; resetDelay = StartDelayDelta; delay = 0; TextureChange = args[4]; } secnum = -1; validcount++; while ((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0) { sec = §ors[secnum]; Texture = sec->floorpic; StartHeight = sec->floorheight; // ALREADY MOVING? IF SO, KEEP GOING... if (sec->specialdata) continue; QueueStairSector(sec, 0, sec->floorheight); sec->special = 0; } while((qSec = DequeueStairSector(&type, &height)) != NULL) { ProcessStairSector(qSec, type, height, stairsType, delay, resetDelay); } return(1); }
static int CmdChangeCeiling(void) { int tag; int flat; int sectorIndex; flat = R_FlatNumForName(ACStrings[Pop()]); tag = Pop(); sectorIndex = -1; while ((sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0) { sectors[sectorIndex].ceilingpic = flat; } return SCRIPT_CONTINUE; }
// // EV_SetLight // // haleyjd 01/09/07: Depending on the value of "type", this function // sets, adds to, or subtracts from all tagged sectors' light levels. // int EV_SetLight(line_t *line, int tag, setlight_e type, int lvl) { int i, rtn = 0; sector_t *s; bool backside = false; if(line && tag == 0) { if(!line->backsector) return rtn; i = line->backsector - sectors; backside = true; goto dobackside; } for(i = -1; (i = P_FindSectorFromTag(tag, i)) >= 0;) { dobackside: s = §ors[i]; rtn = 1; // if any sector is changed, we return 1 switch(type) { case setlight_set: s->lightlevel = lvl; break; case setlight_add: s->lightlevel += lvl; break; case setlight_sub: s->lightlevel -= lvl; break; } if(s->lightlevel < 0) s->lightlevel = 0; else if(s->lightlevel > 255) s->lightlevel = 255; if(backside) break; } return rtn; }
void EV_LightChange (int tag, int value) { int secnum = -1; while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) { sectors[secnum].SetLightLevel(sectors[secnum].lightlevel + value); // [BC] Flag the sector as having its light level altered. That way, when clients // connect, we can tell them about the updated light level. sectors[secnum].bLightChange = true; // [BC] If we're the server, tell clients about the light level change. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_SetSectorLightLevel( secnum ); } }
void EV_LightTurnOn (int tag, int bright) { int secnum = -1; // [RH] Don't do a linear search while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) { sector_t *sector = sectors + secnum; int tbright = bright; //jff 5/17/98 search for maximum PER sector // bright = -1 means to search ([RH] Not 0) // for highest light level // surrounding sector if (bright < 0) { int j; for (j = 0; j < sector->linecount; j++) { sector_t *temp = getNextSector (sector->lines[j], sector); if (!temp) continue; if (temp->lightlevel > tbright) tbright = temp->lightlevel; } } sector->SetLightLevel(tbright); //jff 5/17/98 unless compatibility optioned //then maximum near ANY tagged sector if (i_compatflags & COMPATF_LIGHT) { bright = tbright; } // [BC] Flag the sector as having its light level altered. That way, when clients // connect, we can tell them about the updated light level. sector->bLightChange = true; // [BC] If we're the server, tell clients about the light level change. if ( NETWORK_GetState( ) == NETSTATE_SERVER ) SERVERCOMMANDS_SetSectorLightLevel( secnum ); } }
static int CmdChangeCeilingDirect(void) { int tag; int flat; int sectorIndex; tag = LONG(*PCodePtr); ++PCodePtr; flat = R_FlatNumForName(ACStrings[LONG(*PCodePtr)]); ++PCodePtr; sectorIndex = -1; while ((sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0) { sectors[sectorIndex].ceilingpic = flat; } return SCRIPT_CONTINUE; }