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); } }
void T_Glow(glow_t *g) { float lightLevel = P_GetFloatp(g->sector, DMU_LIGHT_LEVEL); float glowDelta = (1.0f / 255.0f) * (float) GLOWSPEED; switch(g->direction) { case -1: // Down. lightLevel -= glowDelta; if(lightLevel <= g->minLight) { lightLevel += glowDelta; g->direction = 1; } break; case 1: // Up. lightLevel += glowDelta; if(lightLevel >= g->maxLight) { lightLevel -= glowDelta; g->direction = -1; } break; default: Con_Error("T_Glow: Invalid direction %i.", g->direction); break; } P_SetFloatp(g->sector, DMU_LIGHT_LEVEL, lightLevel); }
void T_Glow(glow_t *g) { float lightlevel = P_GetFloatp(g->sector, DMU_LIGHT_LEVEL); float glowDelta = (1.0f / 255.0f) * (float) GLOWSPEED; switch(g->direction) { case -1: // DOWN lightlevel -= glowDelta; if(lightlevel <= g->minLight) { lightlevel += glowDelta; g->direction = 1; } break; case 1: // UP lightlevel += glowDelta; if(lightlevel >= g->maxLight) { lightlevel -= glowDelta; g->direction = -1; } break; } P_SetFloatp(g->sector, DMU_LIGHT_LEVEL, lightlevel); }
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 P_CopySector(Sector *dest, Sector *src) { xsector_t *xsrc = P_ToXSector(src); xsector_t *xdest = P_ToXSector(dest); if(src == dest) return; // no point copying self. // Copy the built-in properties. float ftemp[4]; coord_t dtemp[2]; P_SetFloatp (dest, DMU_LIGHT_LEVEL, P_GetFloatp(src, DMU_LIGHT_LEVEL)); P_GetFloatpv (src, DMU_COLOR, ftemp); P_SetFloatpv (dest, DMU_COLOR, ftemp); P_SetDoublep (dest, DMU_FLOOR_HEIGHT, P_GetDoublep(src, DMU_FLOOR_HEIGHT)); P_SetPtrp (dest, DMU_FLOOR_MATERIAL, P_GetPtrp(src, DMU_FLOOR_MATERIAL)); P_GetFloatpv (src, DMU_FLOOR_COLOR, ftemp); P_SetFloatpv (dest, DMU_FLOOR_COLOR, ftemp); P_GetDoublepv(src, DMU_FLOOR_MATERIAL_OFFSET_XY, dtemp); P_SetDoublepv(dest, DMU_FLOOR_MATERIAL_OFFSET_XY, dtemp); P_SetIntp (dest, DMU_FLOOR_SPEED, P_GetIntp(src, DMU_FLOOR_SPEED)); P_SetDoublep (dest, DMU_FLOOR_TARGET_HEIGHT, P_GetFloatp(src, DMU_FLOOR_TARGET_HEIGHT)); P_SetDoublep (dest, DMU_CEILING_HEIGHT, P_GetDoublep(src, DMU_CEILING_HEIGHT)); P_SetPtrp (dest, DMU_CEILING_MATERIAL, P_GetPtrp(src, DMU_CEILING_MATERIAL)); P_GetFloatpv (src, DMU_CEILING_COLOR, ftemp); P_SetFloatpv (dest, DMU_CEILING_COLOR, ftemp); P_GetDoublepv(src, DMU_CEILING_MATERIAL_OFFSET_XY, dtemp); P_SetDoublepv(dest, DMU_CEILING_MATERIAL_OFFSET_XY, dtemp); P_SetIntp (dest, DMU_CEILING_SPEED, P_GetIntp(src, DMU_CEILING_SPEED)); P_SetDoublep (dest, DMU_CEILING_TARGET_HEIGHT, P_GetFloatp(src, DMU_CEILING_TARGET_HEIGHT)); // Copy the extended properties too #if __JDOOM__ || __JHERETIC__ || __JDOOM64__ xdest->special = xsrc->special; xdest->soundTraversed = xsrc->soundTraversed; xdest->soundTarget = xsrc->soundTarget; #if __JHERETIC__ xdest->seqType = xsrc->seqType; #endif xdest->SP_floororigheight = xsrc->SP_floororigheight; xdest->SP_ceilorigheight = xsrc->SP_ceilorigheight; xdest->origLight = xsrc->origLight; std::memcpy(xdest->origRGB, xsrc->origRGB, sizeof(float) * 3); if(xsrc->xg && xdest->xg) std::memcpy(xdest->xg, xsrc->xg, sizeof(*xdest->xg)); else xdest->xg = 0; #else xdest->special = xsrc->special; xdest->soundTraversed = xsrc->soundTraversed; xdest->soundTarget = xsrc->soundTarget; xdest->seqType = xsrc->seqType; #endif }
void T_FireFlicker(fireflicker_t *flick) { float lightlevel = P_GetFloatp(flick->sector, DMU_LIGHT_LEVEL); float amount; if(--flick->count) return; amount = ((P_Random() & 3) * 16) / 255.0f; if(lightlevel - amount < flick->minLight) P_SetFloatp(flick->sector, DMU_LIGHT_LEVEL, flick->minLight); else P_SetFloatp(flick->sector, DMU_LIGHT_LEVEL, flick->maxLight - amount); flick->count = 4; }
/** * Strobe light flashing. */ void T_StrobeFlash(strobe_t *flash) { float lightlevel = P_GetFloatp(flash->sector, DMU_LIGHT_LEVEL); if(--flash->count) return; if(lightlevel == flash->minLight) { P_SetFloatp(flash->sector, DMU_LIGHT_LEVEL, flash->maxLight); flash->count = flash->brightTime; } else { P_SetFloatp(flash->sector, DMU_LIGHT_LEVEL, flash->minLight); flash->count = flash->darkTime; } }
/** * Broken light flashing. */ void T_LightFlash(lightflash_t *flash) { float lightlevel = P_GetFloatp(flash->sector, DMU_LIGHT_LEVEL); if(--flash->count) return; if(lightlevel == flash->maxLight) { P_SetFloatp(flash->sector, DMU_LIGHT_LEVEL, flash->minLight); flash->count = (P_Random() & flash->minTime) + 1; } else { P_SetFloatp(flash->sector, DMU_LIGHT_LEVEL, flash->maxLight); flash->count = (P_Random() & flash->maxTime) + 1; } }
void T_FloorWaggle(waggle_t *waggle) { DENG_ASSERT(waggle != 0); switch(waggle->state) { default: case WS_STABLE: if(waggle->ticker != -1) { if(!--waggle->ticker) { waggle->state = WS_REDUCE; } } break; case WS_EXPAND: if((waggle->scale += waggle->scaleDelta) >= waggle->targetScale) { waggle->scale = waggle->targetScale; waggle->state = WS_STABLE; } break; case WS_REDUCE: if((waggle->scale -= waggle->scaleDelta) <= 0) { // Remove. P_SetDoublep(waggle->sector, DMU_FLOOR_HEIGHT, waggle->originalHeight); P_ChangeSector(waggle->sector, 1 /*crush damage*/); P_ToXSector(waggle->sector)->specialData = nullptr; P_NotifySectorFinished(P_ToXSector(waggle->sector)->tag); Thinker_Remove(&waggle->thinker); return; } break; } waggle->accumulator += waggle->accDelta; coord_t fh = waggle->originalHeight + FLOATBOBOFFSET(((int) waggle->accumulator) & 63) * waggle->scale; P_SetDoublep(waggle->sector, DMU_FLOOR_HEIGHT, fh); P_SetDoublep(waggle->sector, DMU_FLOOR_TARGET_HEIGHT, fh); P_SetFloatp(waggle->sector, DMU_FLOOR_SPEED, 0); P_ChangeSector(waggle->sector, 1 /*crush damage*/); }
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); }
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); } }
static void P_v13_UnArchiveWorld(void) { int i, j; fixed_t offx, offy; Sector* sec; xsector_t* xsec; Line* line; xline_t* xline; // Do sectors. for(i = 0; i < numsectors; ++i) { Uri *floorTextureUrn, *ceilingTextureUrn; sec = P_ToPtr(DMU_SECTOR, i); xsec = P_ToXSector(sec); P_SetDoublep(sec, DMU_FLOOR_HEIGHT, (coord_t)Reader_ReadInt16(svReader)); P_SetDoublep(sec, DMU_CEILING_HEIGHT, (coord_t)Reader_ReadInt16(svReader)); floorTextureUrn = readTextureUrn(svReader, "Flats"); P_SetPtrp(sec, DMU_FLOOR_MATERIAL, DD_MaterialForTextureUri(floorTextureUrn)); Uri_Delete(floorTextureUrn); ceilingTextureUrn = readTextureUrn(svReader, "Flats"); P_SetPtrp(sec, DMU_CEILING_MATERIAL, DD_MaterialForTextureUri(ceilingTextureUrn)); Uri_Delete(ceilingTextureUrn); P_SetFloatp(sec, DMU_LIGHT_LEVEL, (float) (Reader_ReadInt16(svReader)) / 255.0f); xsec->special = Reader_ReadInt16(svReader); // needed? /*xsec->tag = **/Reader_ReadInt16(svReader); // needed? xsec->specialData = 0; xsec->soundTarget = 0; } // Do lines. for(i = 0; i < numlines; ++i) { line = P_ToPtr(DMU_LINE, i); xline = P_ToXLine(line); xline->flags = Reader_ReadInt16(svReader); xline->special = Reader_ReadInt16(svReader); /*xline->tag =*/Reader_ReadInt16(svReader); for(j = 0; j < 2; ++j) { Uri *topTextureUrn, *bottomTextureUrn, *middleTextureUrn; Side* sdef = P_GetPtrp(line, j == 0? DMU_FRONT : DMU_BACK); if(!sdef) continue; offx = Reader_ReadInt16(svReader) << FRACBITS; offy = Reader_ReadInt16(svReader) << FRACBITS; P_SetFixedp(sdef, DMU_TOP_MATERIAL_OFFSET_X, offx); P_SetFixedp(sdef, DMU_TOP_MATERIAL_OFFSET_Y, offy); P_SetFixedp(sdef, DMU_MIDDLE_MATERIAL_OFFSET_X, offx); P_SetFixedp(sdef, DMU_MIDDLE_MATERIAL_OFFSET_Y, offy); P_SetFixedp(sdef, DMU_BOTTOM_MATERIAL_OFFSET_X, offx); P_SetFixedp(sdef, DMU_BOTTOM_MATERIAL_OFFSET_Y, offy); topTextureUrn = readTextureUrn(svReader, "Textures"); P_SetPtrp(sdef, DMU_TOP_MATERIAL, DD_MaterialForTextureUri(topTextureUrn)); Uri_Delete(topTextureUrn); bottomTextureUrn = readTextureUrn(svReader, "Textures"); P_SetPtrp(sdef, DMU_BOTTOM_MATERIAL, DD_MaterialForTextureUri(bottomTextureUrn)); Uri_Delete(bottomTextureUrn); middleTextureUrn = readTextureUrn(svReader, "Textures"); P_SetPtrp(sdef, DMU_MIDDLE_MATERIAL, DD_MaterialForTextureUri(middleTextureUrn)); Uri_Delete(middleTextureUrn); } } }
void P_SectorModifyLightx(Sector* sector, fixed_t value) { P_SetFloatp(sector, DMU_LIGHT_LEVEL, P_SectorLight(sector) + FIX2FLT(value) / 255.0f); }
void P_SectorSetLight(Sector* sector, float level) { P_SetFloatp(sector, DMU_LIGHT_LEVEL, level); }
void SV_ReadSector(Sector *sec, MapStateReader *msr) { xsector_t *xsec = P_ToXSector(sec); Reader1 *reader = msr->reader(); int mapVersion = msr->mapVersion(); // A type byte? int type = 0; #if __JHEXEN__ if(mapVersion < 4) type = sc_ploff; else #else if(mapVersion <= 1) type = sc_normal; else #endif type = Reader_ReadByte(reader); // A version byte? int ver = 1; #if __JHEXEN__ if(mapVersion > 2) #else if(mapVersion > 4) #endif { ver = Reader_ReadByte(reader); } int fh = Reader_ReadInt16(reader); int ch = Reader_ReadInt16(reader); P_SetIntp(sec, DMU_FLOOR_HEIGHT, fh); P_SetIntp(sec, DMU_CEILING_HEIGHT, ch); #if __JHEXEN__ // Update the "target heights" of the planes. P_SetIntp(sec, DMU_FLOOR_TARGET_HEIGHT, fh); P_SetIntp(sec, DMU_CEILING_TARGET_HEIGHT, ch); // The move speed is not saved; can cause minor problems. P_SetIntp(sec, DMU_FLOOR_SPEED, 0); P_SetIntp(sec, DMU_CEILING_SPEED, 0); #endif world_Material *floorMaterial = 0, *ceilingMaterial = 0; #if !__JHEXEN__ if(mapVersion == 1) { // The flat numbers are absolute lump indices. de::Uri uri("Flats:", RC_NULL); uri.setPath(CentralLumpIndex()[Reader_ReadInt16(reader)].name().fileNameWithoutExtension()); floorMaterial = (world_Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(reinterpret_cast<uri_s *>(&uri))); uri.setPath(CentralLumpIndex()[Reader_ReadInt16(reader)].name().fileNameWithoutExtension()); ceilingMaterial = (world_Material *)P_ToPtr(DMU_MATERIAL, Materials_ResolveUri(reinterpret_cast<uri_s *>(&uri))); } else if(mapVersion >= 4) #endif { // The flat numbers are actually archive numbers. floorMaterial = msr->material(Reader_ReadInt16(reader), 0); ceilingMaterial = msr->material(Reader_ReadInt16(reader), 0); } P_SetPtrp(sec, DMU_FLOOR_MATERIAL, floorMaterial); P_SetPtrp(sec, DMU_CEILING_MATERIAL, ceilingMaterial); if(ver >= 3) { P_SetIntp(sec, DMU_FLOOR_FLAGS, Reader_ReadInt16(reader)); P_SetIntp(sec, DMU_CEILING_FLAGS, Reader_ReadInt16(reader)); } byte lightlevel; #if __JHEXEN__ lightlevel = (byte) Reader_ReadInt16(reader); #else // In Ver1 the light level is a short if(mapVersion == 1) { lightlevel = (byte) Reader_ReadInt16(reader); } else { lightlevel = Reader_ReadByte(reader); } #endif P_SetFloatp(sec, DMU_LIGHT_LEVEL, (float) lightlevel / 255.f); #if !__JHEXEN__ if(mapVersion > 1) #endif { byte rgb[3]; Reader_Read(reader, rgb, 3); for(int i = 0; i < 3; ++i) P_SetFloatp(sec, DMU_COLOR_RED + i, rgb[i] / 255.f); } // Ver 2 includes surface colours if(ver >= 2) { byte rgb[3]; Reader_Read(reader, rgb, 3); for(int i = 0; i < 3; ++i) P_SetFloatp(sec, DMU_FLOOR_COLOR_RED + i, rgb[i] / 255.f); Reader_Read(reader, rgb, 3); for(int i = 0; i < 3; ++i) P_SetFloatp(sec, DMU_CEILING_COLOR_RED + i, rgb[i] / 255.f); } xsec->special = Reader_ReadInt16(reader); /*xsec->tag =*/ Reader_ReadInt16(reader); #if __JHEXEN__ xsec->seqType = seqtype_t(Reader_ReadInt16(reader)); #endif if(type == sc_ploff #if !__JHEXEN__ || type == sc_xg1 #endif ) { P_SetFloatp(sec, DMU_FLOOR_MATERIAL_OFFSET_X, Reader_ReadFloat(reader)); P_SetFloatp(sec, DMU_FLOOR_MATERIAL_OFFSET_Y, Reader_ReadFloat(reader)); P_SetFloatp(sec, DMU_CEILING_MATERIAL_OFFSET_X, Reader_ReadFloat(reader)); P_SetFloatp(sec, DMU_CEILING_MATERIAL_OFFSET_Y, Reader_ReadFloat(reader)); } #if !__JHEXEN__ if(type == sc_xg1) { SV_ReadXGSector(sec, reader, mapVersion); } #endif #if !__JHEXEN__ if(mapVersion <= 1) #endif { xsec->specialData = 0; } // We'll restore the sound targets latter on xsec->soundTarget = 0; }