void EV_TurnTagLightsOff(linedef_t *line) { int j; float min; float lightlevel; sector_t *sec = NULL, *tsec; linedef_t *other; iterlist_t *list; list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); if(!list) return; P_IterListResetIterator(list, true); while((sec = P_IterListIterator(list)) != NULL) { min = P_GetFloatp(sec, DMU_LIGHT_LEVEL); for(j = 0; j < P_GetIntp(sec, DMU_LINEDEF_COUNT); ++j) { other = P_GetPtrp(sec, DMU_LINEDEF_OF_SECTOR | j); tsec = P_GetNextSector(other, sec); if(!tsec) continue; lightlevel = P_GetFloatp(tsec, DMU_LIGHT_LEVEL); if(lightlevel < min) min = lightlevel; } P_SetFloatp(sec, DMU_LIGHT_LEVEL, min); } }
void EV_LightTurnOn(Line *line, float max) { iterlist_t *list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); if(!list) return; float lightLevel = 0; if(NON_ZERO(max)) lightLevel = max; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); Sector *sec; while((sec = (Sector *)IterList_MoveIterator(list))) { // If Max = 0 means to search for the highest light level in the // surrounding sector. if(IS_ZERO(max)) { lightLevel = P_GetFloatp(sec, DMU_LIGHT_LEVEL); float otherLevel = DDMINFLOAT; P_FindSectorSurroundingHighestLight(sec, &otherLevel); if(otherLevel > lightLevel) lightLevel = otherLevel; } P_SetFloatp(sec, DMU_LIGHT_LEVEL, lightLevel); } }
static mobj_t* getTeleportDestination(short tag) { iterlist_t* list; list = P_GetSectorIterListForTag(tag, false); if(list) { Sector* sec = NULL; findmobjparams_t params; params.type = MT_TELEPORTMAN; params.foundMobj = NULL; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); while((sec = IterList_MoveIterator(list)) != NULL) { params.sec = sec; if(Thinker_Iterate(P_MobjThinker, findMobj, ¶ms)) { // Found one. return params.foundMobj; } } } return NULL; }
void P_BuildSectorTagLists() { P_DestroySectorTagLists(); for(int i = 0; i < numsectors; ++i) { Sector *sec = (Sector *)P_ToPtr(DMU_SECTOR, i); xsector_t *xsec = P_ToXSector(sec); if(xsec->tag) { iterlist_t *list = P_GetSectorIterListForTag(xsec->tag, true); IterList_PushBack(list, sec); } } }
/** * Start strobing lights (usually from a trigger) */ void EV_StartLightStrobing(Line *line) { iterlist_t *list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); if(!list) return; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); Sector *sec; while((sec = (Sector *)IterList_MoveIterator(list))) { if(P_ToXSector(sec)->specialData) continue; P_SpawnStrobeFlash(sec, SLOWDARK, 0); } }
/** * Start strobing lights (usually from a trigger). */ void EV_StartLightStrobing(linedef_t *line) { sector_t *sec = NULL; iterlist_t *list; list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); if(!list) return; P_IterListResetIterator(list, true); while((sec = P_IterListIterator(list)) != NULL) { if(P_ToXSector(sec)->specialData) continue; P_SpawnStrobeFlash(sec, SLOWDARK, 0); } }
void EV_TurnTagLightsOff(Line *line) { iterlist_t *list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); if(!list) return; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); Sector *sec; while((sec = (Sector *)IterList_MoveIterator(list))) { float lightLevel = P_GetFloatp(sec, DMU_LIGHT_LEVEL); float otherLevel = DDMAXFLOAT; P_FindSectorSurroundingLowestLight(sec, &otherLevel); if(otherLevel < lightLevel) lightLevel = otherLevel; P_SetFloatp(sec, DMU_LIGHT_LEVEL, lightLevel); } }
/** * d64tc */ void P_ThunderSector() { if(!(P_Random() < 10)) return; iterlist_t *list = P_GetSectorIterListForTag(20000, false); if(!list) return; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); Sector *sec; while((sec = (Sector *)IterList_MoveIterator(list))) { if(!(mapTime & 32)) { P_SetFloatp(sec, DMU_LIGHT_LEVEL, 1); } } S_StartSound(SFX_SSSIT | DDSF_NO_ATTENUATION, NULL); }
dd_bool EV_StartFloorWaggle(int tag, int height, int speed, int offset, int timer) { iterlist_t *list = P_GetSectorIterListForTag(tag, false); if(!list) return false; dd_bool retCode = false; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); Sector *sec; while((sec = (Sector *)IterList_MoveIterator(list))) { if(P_ToXSector(sec)->specialData) continue; // Already moving, so keep going... retCode = true; waggle_t *waggle = (waggle_t *)Z_Calloc(sizeof(*waggle), PU_MAP, 0); waggle->thinker.function = (thinkfunc_t) T_FloorWaggle; Thinker_Add(&waggle->thinker); P_ToXSector(sec)->specialData = waggle; waggle->sector = sec; waggle->originalHeight = P_GetDoublep(sec, DMU_FLOOR_HEIGHT); waggle->accumulator = offset; waggle->accDelta = FIX2FLT(speed << 10); waggle->scale = 0; waggle->targetScale = FIX2FLT(height << 10); waggle->scaleDelta = FIX2FLT(FLT2FIX(waggle->targetScale) / (TICSPERSEC + ((3 * TICSPERSEC) * height) / 255)); waggle->ticker = timer ? timer * 35 : -1; waggle->state = WS_EXPAND; } return retCode; }
void EV_LightTurnOn(linedef_t *line, float max) { int j; float lightlevel; sector_t *sec = NULL, *tsec; linedef_t *tline; iterlist_t *list; list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); if(!list) return; P_IterListResetIterator(list, true); while((sec = P_IterListIterator(list)) != NULL) { // max = 0 means to search // for highest light level // surrounding sector if(!max) { for(j = 0; j < P_GetIntp(sec, DMU_LINEDEF_COUNT); ++j) { tline = P_GetPtrp(sec, DMU_LINEDEF_OF_SECTOR | j); tsec = P_GetNextSector(tline, sec); if(!tsec) continue; lightlevel = P_GetFloatp(tsec, DMU_LIGHT_LEVEL); if(lightlevel > max) max = lightlevel; } } P_SetFloatp(sec, DMU_LIGHT_LEVEL, max); } }
int EV_OpenPillar(Line * /*line*/, byte *args) { iterlist_t *list = P_GetSectorIterListForTag((int) args[0], false); if(!list) return 0; int rtn = 0; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); Sector *sec; while((sec = (Sector *)IterList_MoveIterator(list))) { // If already moving keep going... if(P_ToXSector(sec)->specialData) continue; if(!FEQUAL(P_GetDoublep(sec, DMU_FLOOR_HEIGHT), P_GetDoublep(sec, DMU_CEILING_HEIGHT))) continue; // Pillar isn't closed. rtn = 1; pillar_t *pillar = (pillar_t *)Z_Calloc(sizeof(*pillar), PU_MAP, 0); pillar->thinker.function = (thinkfunc_t) T_BuildPillar; Thinker_Add(&pillar->thinker); P_ToXSector(sec)->specialData = pillar; pillar->sector = sec; if(!args[2]) { P_FindSectorSurroundingLowestFloor(sec, P_GetDoublep(sec, DMU_FLOOR_HEIGHT), &pillar->floorDest); } else { pillar->floorDest = P_GetDoublep(sec, DMU_FLOOR_HEIGHT) - (coord_t) args[2]; } if(!args[3]) { P_FindSectorSurroundingHighestCeiling(sec, 0, &pillar->ceilingDest); } else { pillar->ceilingDest = P_GetDoublep(sec, DMU_CEILING_HEIGHT) + (coord_t) args[3]; } if(P_GetDoublep(sec, DMU_FLOOR_HEIGHT) - pillar->floorDest >= pillar->ceilingDest - P_GetDoublep(sec, DMU_CEILING_HEIGHT)) { pillar->floorSpeed = (float) args[1] * (1.0f / 8); pillar->ceilingSpeed = (P_GetDoublep(sec, DMU_CEILING_HEIGHT) - pillar->ceilingDest) * (pillar->floorSpeed / (pillar->floorDest - P_GetDoublep(sec, DMU_FLOOR_HEIGHT))); } else { pillar->ceilingSpeed = (float) args[1] * (1.0f / 8); pillar->floorSpeed = (pillar->floorDest - P_GetDoublep(sec, DMU_FLOOR_HEIGHT)) * (pillar->ceilingSpeed / (P_GetDoublep(sec, DMU_CEILING_HEIGHT) - pillar->ceilingDest)); } pillar->direction = -1; // Open the pillar. SN_StartSequence((mobj_t *)P_GetPtrp(pillar->sector, DMU_EMITTER), SEQ_PLATFORM + P_ToXSector(pillar->sector)->seqType); } return rtn; }
int EV_BuildPillar(Line * /*line*/, byte *args, dd_bool crush) { iterlist_t *list = P_GetSectorIterListForTag((int) args[0], false); if(!list) return 0; int rtn = 0; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); Sector *sec; while((sec = (Sector *)IterList_MoveIterator(list))) { // If already moving keep going... if(P_ToXSector(sec)->specialData) continue; if(FEQUAL(P_GetDoublep(sec, DMU_FLOOR_HEIGHT), P_GetDoublep(sec, DMU_CEILING_HEIGHT))) continue; // Pillar is already closed. rtn = 1; coord_t newHeight = 0; if(!args[2]) { newHeight = P_GetDoublep(sec, DMU_FLOOR_HEIGHT) + ((P_GetDoublep(sec, DMU_CEILING_HEIGHT) - P_GetDoublep(sec, DMU_FLOOR_HEIGHT)) * .5f); } else { newHeight = P_GetDoublep(sec, DMU_FLOOR_HEIGHT) + (coord_t) args[2]; } pillar_t *pillar = (pillar_t *)Z_Calloc(sizeof(*pillar), PU_MAP, 0); pillar->thinker.function = (thinkfunc_t) T_BuildPillar; Thinker_Add(&pillar->thinker); P_ToXSector(sec)->specialData = pillar; pillar->sector = sec; if(!args[2]) { pillar->ceilingSpeed = pillar->floorSpeed = (float) args[1] * (1.0f / 8); } else if(newHeight - P_GetDoublep(sec, DMU_FLOOR_HEIGHT) > P_GetDoublep(sec, DMU_CEILING_HEIGHT) - newHeight) { pillar->floorSpeed = (float) args[1] * (1.0f / 8); pillar->ceilingSpeed = (P_GetDoublep(sec, DMU_CEILING_HEIGHT) - newHeight) * (pillar->floorSpeed / (newHeight - P_GetDoublep(sec, DMU_FLOOR_HEIGHT))); } else { pillar->ceilingSpeed = (float) args[1] * (1.0f / 8); pillar->floorSpeed = (newHeight - P_GetDoublep(sec, DMU_FLOOR_HEIGHT)) * (pillar->ceilingSpeed / (P_GetDoublep(sec, DMU_CEILING_HEIGHT) - newHeight)); } pillar->floorDest = newHeight; pillar->ceilingDest = newHeight; pillar->direction = 1; pillar->crush = crush * (int) args[3]; SN_StartSequence((mobj_t *)P_GetPtrp(pillar->sector, DMU_EMITTER), SEQ_PLATFORM + P_ToXSector(pillar->sector)->seqType); } return rtn; }
int EV_Teleport(linedef_t *line, int side, mobj_t *thing) { float oldpos[3]; float aboveFloor; mobj_t *m; thinker_t *thinker; sector_t *sec = NULL, *sector; iterlist_t *list; if(thing->flags2 & MF2_NOTELEPORT) return 0; // Don't teleport if hit back of line, // so you can get out of teleporter. if(side == 1) return 0; list = P_GetSectorIterListForTag(P_ToXLine(line)->tag, false); if(!list) return 0; P_IterListResetIterator(list, true); while((sec = P_IterListIterator(list)) != NULL) { thinker = thinkerCap.next; for(thinker = thinkerCap.next; thinker != &thinkerCap; thinker = thinker->next) { // not a mobj if(thinker->function != P_MobjThinker) continue; m = (mobj_t *) thinker; // not a teleportman if(m->type != MT_TELEPORTMAN) continue; sector = P_GetPtrp(m->subsector, DMU_SECTOR); // wrong sector if(sector != sec) continue; memcpy(oldpos, thing->pos, sizeof(thing->pos)); aboveFloor = thing->pos[VZ] - thing->floorZ; if(!P_TeleportMove(thing, m->pos[VX], m->pos[VY], false)) return 0; // In Final Doom things teleported to their destination // but the height wasn't set to the floor. if(gamemission != GM_TNT && gamemission != GM_PLUT) thing->pos[VZ] = thing->floorZ; #if 0 // Spawn teleport fog at source and destination. fog = P_SpawnMobj3fv(MT_TFOG, oldpos); S_StartSound(SFX_TELEPT, fog); an = m->angle >> ANGLETOFINESHIFT; fog = P_SpawnMobj3f(MT_TFOG, m->pos[VX] + 20 * FIX2FLT(finecosine[an]), m->pos[VY] + 20 * FIX2FLT(finesine[an]), thing->pos[VZ]); // Emit sound, where? S_StartSound(SFX_TELEPT, fog); #endif thing->angle = m->angle; if(thing->flags2 & MF2_FLOORCLIP) { thing->floorClip = 0; if(thing->pos[VZ] == P_GetFloatp(thing->subsector, DMU_FLOOR_HEIGHT)) { const terraintype_t* tt = P_MobjGetFloorTerrainType(thing); if(tt->flags & TTF_FLOORCLIP) { thing->floorClip = 10; } } } thing->mom[MX] = thing->mom[MY] = thing->mom[MZ] = 0; // don't move for a bit if(thing->player) { thing->reactionTime = 18; if(thing->player->powers[PT_FLIGHT] && aboveFloor) { thing->pos[VZ] = thing->floorZ + aboveFloor; if(thing->pos[VZ] + thing->height > thing->ceilingZ) { thing->pos[VZ] = thing->ceilingZ - thing->height; } thing->dPlayer->viewZ = thing->pos[VZ] + thing->dPlayer->viewHeight; } else { //thing->dPlayer->clLookDir = 0; /* $unifiedangles */ thing->dPlayer->lookDir = 0; } //thing->dPlayer->clAngle = thing->angle; /* $unifiedangles */ thing->dPlayer->flags |= DDPF_FIXANGLES | DDPF_FIXPOS | DDPF_FIXMOM; } return 1; } } return 0; }
static int doPlat(Line *line, int tag, plattype_e type, int amount) #endif { #if !__JHEXEN__ Sector *frontSector = (Sector *)P_GetPtrp(line, DMU_FRONT_SECTOR); #endif iterlist_t *list = P_GetSectorIterListForTag(tag, false); if(!list) return 0; int rtn = 0; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); Sector *sec; while((sec = (Sector *)IterList_MoveIterator(list))) { xsector_t *xsec = P_ToXSector(sec); if(xsec->specialData) continue; // Find lowest & highest floors around sector rtn = 1; plat_t *plat = (plat_t *) Z_Calloc(sizeof(*plat), PU_MAP, 0); plat->thinker.function = T_PlatRaise; Thinker_Add(&plat->thinker); xsec->specialData = plat; plat->type = type; plat->sector = sec; plat->crush = false; plat->tag = tag; #if __JHEXEN__ plat->speed = (float) args[1] * (1.0 / 8); #endif coord_t floorHeight = P_GetDoublep(sec, DMU_FLOOR_HEIGHT); switch(type) { #if !__JHEXEN__ case PT_RAISETONEARESTANDCHANGE: plat->speed = PLATSPEED * .5; P_SetPtrp(sec, DMU_FLOOR_MATERIAL, P_GetPtrp(frontSector, DMU_FLOOR_MATERIAL)); { coord_t nextFloor; if(P_FindSectorSurroundingNextHighestFloor(sec, floorHeight, &nextFloor)) plat->high = nextFloor; else plat->high = floorHeight; } plat->wait = 0; plat->state = PS_UP; // No more damage if applicable. xsec->special = 0; S_PlaneSound((Plane *)P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMMOVE); break; case PT_RAISEANDCHANGE: plat->speed = PLATSPEED * .5; P_SetPtrp(sec, DMU_FLOOR_MATERIAL, P_GetPtrp(frontSector, DMU_FLOOR_MATERIAL)); plat->high = floorHeight + amount; plat->wait = 0; plat->state = PS_UP; S_PlaneSound((Plane *)P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMMOVE); break; #endif case PT_DOWNWAITUPSTAY: P_FindSectorSurroundingLowestFloor(sec, P_GetDoublep(sec, DMU_FLOOR_HEIGHT), &plat->low); #if __JHEXEN__ plat->low += 8; #else plat->speed = PLATSPEED * 4; #endif if(plat->low > floorHeight) plat->low = floorHeight; plat->high = floorHeight; plat->state = PS_DOWN; #if __JHEXEN__ plat->wait = (int) args[2]; #else plat->wait = PLATWAIT * TICSPERSEC; #endif #if !__JHEXEN__ S_PlaneSound((Plane *)P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMSTART); #endif break; #if __JDOOM64__ || __JHEXEN__ case PT_UPWAITDOWNSTAY: P_FindSectorSurroundingHighestFloor(sec, -500, &plat->high); if(plat->high < floorHeight) plat->high = floorHeight; plat->low = floorHeight; plat->state = PS_UP; # if __JHEXEN__ plat->wait = (int) args[2]; # else plat->wait = PLATWAIT * TICSPERSEC; # endif # if __JDOOM64__ plat->speed = PLATSPEED * 8; S_PlaneSound((Plane *)P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMSTART); # endif break; #endif #if __JDOOM64__ case PT_DOWNWAITUPDOOR: // jd64 plat->speed = PLATSPEED * 8; P_FindSectorSurroundingLowestFloor(sec, P_GetDoublep(sec, DMU_FLOOR_HEIGHT), &plat->low); if(plat->low > floorHeight) plat->low = floorHeight; if(plat->low != floorHeight) plat->low += 6; plat->high = floorHeight; plat->wait = 50 * PLATWAIT; plat->state = PS_DOWN; break; #endif #if __JHEXEN__ case PT_DOWNBYVALUEWAITUPSTAY: plat->low = floorHeight - (coord_t) args[3] * 8; if(plat->low > floorHeight) plat->low = floorHeight; plat->high = floorHeight; plat->wait = (int) args[2]; plat->state = PS_DOWN; break; case PT_UPBYVALUEWAITDOWNSTAY: plat->high = floorHeight + (coord_t) args[3] * 8; if(plat->high < floorHeight) plat->high = floorHeight; plat->low = floorHeight; plat->wait = (int) args[2]; plat->state = PS_UP; break; #endif #if __JDOOM__ || __JDOOM64__ case PT_DOWNWAITUPSTAYBLAZE: plat->speed = PLATSPEED * 8; P_FindSectorSurroundingLowestFloor(sec, P_GetDoublep(sec, DMU_FLOOR_HEIGHT), &plat->low); if(plat->low > floorHeight) plat->low = floorHeight; plat->high = floorHeight; plat->wait = PLATWAIT * TICSPERSEC; plat->state = PS_DOWN; S_PlaneSound((Plane *)P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMSTART); break; #endif case PT_PERPETUALRAISE: P_FindSectorSurroundingLowestFloor(sec, P_GetDoublep(sec, DMU_FLOOR_HEIGHT), &plat->low); #if __JHEXEN__ plat->low += 8; #else plat->speed = PLATSPEED; #endif if(plat->low > floorHeight) plat->low = floorHeight; P_FindSectorSurroundingHighestFloor(sec, -500, &plat->high); if(plat->high < floorHeight) plat->high = floorHeight; plat->state = platstate_e(P_Random() & 1); #if __JHEXEN__ plat->wait = (int) args[2]; #else plat->wait = PLATWAIT * TICSPERSEC; #endif #if !__JHEXEN__ S_PlaneSound((Plane *)P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMSTART); #endif break; default: break; } #if __JHEXEN__ SN_StartSequenceInSec(plat->sector, SEQ_PLATFORM); #endif } return rtn; }
dd_bool EV_SpawnLight(Line * /*line*/, byte *arg, lighttype_t type) { int arg1, arg2, arg3, arg4; arg1 = (int) arg[1]; arg2 = (int) arg[2]; arg3 = (int) arg[3]; arg4 = (int) arg[4]; iterlist_t *list = P_GetSectorIterListForTag((int) arg[0], false); if(!list) return false; dd_bool rtn = false; IterList_SetIteratorDirection(list, ITERLIST_FORWARD); IterList_RewindIterator(list); Sector *sec; while((sec = (Sector *)IterList_MoveIterator(list))) { rtn = true; dd_bool think = false; light_t *light = (light_t *)Z_Calloc(sizeof(*light), PU_MAP, 0); light->type = type; light->sector = sec; light->count = 0; switch(type) { case LITE_RAISEBYVALUE: P_SectorModifyLight(light->sector, (float) arg1 / 255.0f); break; case LITE_LOWERBYVALUE: P_SectorModifyLight(light->sector, -((float) arg1 / 255.0f)); break; case LITE_CHANGETOVALUE: P_SectorSetLight(light->sector, (float) arg1 / 255.0f); break; case LITE_FADE: think = true; light->value1 = (float) arg1 / 255.0f; // Destination lightlevel. light->value2 = FIX2FLT(FixedDiv((arg1 - (int) (255.0f * P_SectorLight(light->sector))) << FRACBITS, arg2 << FRACBITS)) / 255.0f; // Delta lightlevel. if(P_SectorLight(light->sector) <= (float) arg1 / 255.0f) { light->tics2 = 1; // Get brighter. } else { light->tics2 = -1; } break; case LITE_GLOW: think = true; light->value1 = (float) arg1 / 255.0f; // Upper lightlevel. light->value2 = (float) arg2 / 255.0f; // Lower lightlevel. light->tics1 = FixedDiv((arg1 - (int) (255.0f * P_SectorLight(light->sector))) << FRACBITS, arg3 << FRACBITS); // Lightlevel delta. if(P_SectorLight(light->sector) <= (float) arg1 / 255.0f) { light->tics2 = 1; // Get brighter. } else { light->tics2 = -1; } break; case LITE_FLICKER: think = true; light->value1 = (float) arg1 / 255.0f; // Upper lightlevel. light->value2 = (float) arg2 / 255.0f; // Lower lightlevel. P_SectorSetLight(light->sector, light->value1); light->count = (P_Random() & 64) + 1; break; case LITE_STROBE: think = true; light->value1 = (float) arg1 / 255.0f; // Upper lightlevel. light->value2 = (float) arg2 / 255.0f; // Lower lightlevel. light->tics1 = arg3; // Upper tics. light->tics2 = arg4; // Lower tics. light->count = arg3; P_SectorSetLight(light->sector, light->value1); break; default: rtn = false; break; } if(think) { light->thinker.function = (thinkfunc_t) T_Light; Thinker_Add(&light->thinker); } else { Z_Free(light); } } return rtn; }