void T_FireFlicker(void *flickPtr) { fireflicker_t *flick = (fireflicker_t *)flickPtr; float amount, lightLevel; if(--flick->count) return; lightLevel = P_GetFloatp(flick->sector, DMU_LIGHT_LEVEL); 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; }
/** * Broken light flashing. */ void T_LightFlash(lightflash_t *flash) { float lightLevel; if(--flash->count) return; lightLevel = P_GetFloatp(flash->sector, DMU_LIGHT_LEVEL); 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; } }
/** * Strobe light flashing. */ void T_StrobeFlash(strobe_t *flash) { float lightLevel; if(--flash->count) return; lightLevel = P_GetFloatp(flash->sector, DMU_LIGHT_LEVEL); 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; } }
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); } }
void P_SpawnFireFlicker(sector_t *sector) { float lightlevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); fireflicker_t *flick; // Note that we are resetting sector attributes. // Nothing special about it during gameplay. P_ToXSector(sector)->special = 0; flick = Z_Malloc(sizeof(*flick), PU_MAPSPEC, 0); P_ThinkerAdd(&flick->thinker); flick->thinker.function = T_FireFlicker; flick->sector = sector; flick->maxLight = lightlevel; flick->minLight = P_FindMinSurroundingLight(sector, lightlevel) + (16.0f/255.0f); flick->count = 4; }
/** * After the map has been loaded, scan each sector * for specials that spawn thinkers */ void P_SpawnLightFlash(sector_t *sector) { float lightlevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); lightflash_t *flash; // nothing special about it during gameplay P_ToXSector(sector)->special = 0; flash = Z_Malloc(sizeof(*flash), PU_MAPSPEC, 0); P_ThinkerAdd(&flash->thinker); flash->thinker.function = T_LightFlash; flash->sector = sector; flash->maxLight = lightlevel; flash->minLight = P_FindMinSurroundingLight(sector, lightlevel); flash->maxTime = 64; flash->minTime = 7; flash->count = (P_Random() & flash->maxTime) + 1; }
void P_SpawnGlowingLight(Sector *sector) { float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); float otherLevel = DDMAXFLOAT; glow_t *g = (glow_t *)Z_Calloc(sizeof(*g), PU_MAP, 0); g->thinker.function = (thinkfunc_t) T_Glow; Thinker_Add(&g->thinker); g->sector = sector; P_FindSectorSurroundingLowestLight(sector, &otherLevel); if(otherLevel < lightLevel) g->minLight = otherLevel; else g->minLight = lightLevel; g->maxLight = lightLevel; g->direction = -1; // Note that we are resetting sector attributes. // Nothing special about it during gameplay. P_ToXSector(sector)->special = 0; }
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); } }
void P_SpawnFireFlicker(Sector *sector) { float lightLevel = P_GetFloatp(sector, DMU_LIGHT_LEVEL); float otherLevel = DDMAXFLOAT; // Note that we are resetting sector attributes. // Nothing special about it during gameplay. P_ToXSector(sector)->special = 0; fireflicker_t *flick = (fireflicker_t *)Z_Calloc(sizeof(*flick), PU_MAP, 0); flick->thinker.function = T_FireFlicker; Thinker_Add(&flick->thinker); flick->sector = sector; flick->count = 4; flick->maxLight = lightLevel; P_FindSectorSurroundingLowestLight(sector, &otherLevel); if(otherLevel < lightLevel) flick->minLight = otherLevel; else flick->minLight = lightLevel; flick->minLight += (16.0f/255.0f); }
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; }
float P_SectorLight(Sector* sector) { return P_GetFloatp(sector, DMU_LIGHT_LEVEL); }
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. #if 0 // P_Copyp is not implemented in Doomsday yet. P_Copyp(DMU_LIGHT_LEVEL, src, dest); P_Copyp(DMU_COLOR, src, dest); P_Copyp(DMU_FLOOR_HEIGHT, src, dest); P_Copyp(DMU_FLOOR_MATERIAL, src, dest); P_Copyp(DMU_FLOOR_COLOR, src, dest); P_Copyp(DMU_FLOOR_MATERIAL_OFFSET_XY, src, dest); P_Copyp(DMU_FLOOR_SPEED, src, dest); P_Copyp(DMU_FLOOR_TARGET_HEIGHT, src, dest); P_Copyp(DMU_CEILING_HEIGHT, src, dest); P_Copyp(DMU_CEILING_MATERIAL, src, dest); P_Copyp(DMU_CEILING_COLOR, src, dest); P_Copyp(DMU_CEILING_MATERIAL_OFFSET_XY, src, dest); P_Copyp(DMU_CEILING_SPEED, src, dest); P_Copyp(DMU_CEILING_TARGET_HEIGHT, src, dest); #else { 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)); } #endif // 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; memcpy(xdest->origRGB, xsrc->origRGB, sizeof(float) * 3); if(xsrc->xg && xdest->xg) memcpy(xdest->xg, xsrc->xg, sizeof(*xdest->xg)); else xdest->xg = NULL; #else xdest->special = xsrc->special; xdest->soundTraversed = xsrc->soundTraversed; xdest->soundTarget = xsrc->soundTarget; xdest->seqType = xsrc->seqType; #endif }
void SV_WriteSector(Sector *sec, MapStateWriter *msw) { Writer1 *writer = msw->writer(); int i, type; float flooroffx = P_GetFloatp(sec, DMU_FLOOR_MATERIAL_OFFSET_X); float flooroffy = P_GetFloatp(sec, DMU_FLOOR_MATERIAL_OFFSET_Y); float ceiloffx = P_GetFloatp(sec, DMU_CEILING_MATERIAL_OFFSET_X); float ceiloffy = P_GetFloatp(sec, DMU_CEILING_MATERIAL_OFFSET_Y); byte lightlevel = (byte) (255.f * P_GetFloatp(sec, DMU_LIGHT_LEVEL)); short floorheight = (short) P_GetIntp(sec, DMU_FLOOR_HEIGHT); short ceilingheight = (short) P_GetIntp(sec, DMU_CEILING_HEIGHT); short floorFlags = (short) P_GetIntp(sec, DMU_FLOOR_FLAGS); short ceilingFlags = (short) P_GetIntp(sec, DMU_CEILING_FLAGS); world_Material *floorMaterial = (world_Material *)P_GetPtrp(sec, DMU_FLOOR_MATERIAL); world_Material *ceilingMaterial = (world_Material *)P_GetPtrp(sec, DMU_CEILING_MATERIAL); xsector_t *xsec = P_ToXSector(sec); #if !__JHEXEN__ // Determine type. if(xsec->xg) type = sc_xg1; else #endif if(NON_ZERO(flooroffx) || NON_ZERO(flooroffy) || NON_ZERO(ceiloffx) || NON_ZERO(ceiloffy)) type = sc_ploff; else type = sc_normal; // Type byte. Writer_WriteByte(writer, type); // Version. // 2: Surface colors. // 3: Surface flags. Writer_WriteByte(writer, 3); // write a version byte. Writer_WriteInt16(writer, floorheight); Writer_WriteInt16(writer, ceilingheight); Writer_WriteInt16(writer, msw->serialIdFor(floorMaterial)); Writer_WriteInt16(writer, msw->serialIdFor(ceilingMaterial)); Writer_WriteInt16(writer, floorFlags); Writer_WriteInt16(writer, ceilingFlags); #if __JHEXEN__ Writer_WriteInt16(writer, (short) lightlevel); #else Writer_WriteByte(writer, lightlevel); #endif float rgb[3]; P_GetFloatpv(sec, DMU_COLOR, rgb); for(i = 0; i < 3; ++i) Writer_WriteByte(writer, (byte)(255.f * rgb[i])); P_GetFloatpv(sec, DMU_FLOOR_COLOR, rgb); for(i = 0; i < 3; ++i) Writer_WriteByte(writer, (byte)(255.f * rgb[i])); P_GetFloatpv(sec, DMU_CEILING_COLOR, rgb); for(i = 0; i < 3; ++i) Writer_WriteByte(writer, (byte)(255.f * rgb[i])); Writer_WriteInt16(writer, xsec->special); Writer_WriteInt16(writer, xsec->tag); #if __JHEXEN__ Writer_WriteInt16(writer, xsec->seqType); #endif if(type == sc_ploff #if !__JHEXEN__ || type == sc_xg1 #endif ) { Writer_WriteFloat(writer, flooroffx); Writer_WriteFloat(writer, flooroffy); Writer_WriteFloat(writer, ceiloffx); Writer_WriteFloat(writer, ceiloffy); } #if !__JHEXEN__ if(xsec->xg) // Extended General? { SV_WriteXGSector(sec, writer); } #endif }