void EV_SlidingDoor ( line_t* line, mobj_t* thing ) { sector_t* sec; slidedoor_t* door; // DOOM II ONLY... if (gamemode != commercial) return; // Make sure door isn't already being animated sec = line->frontsector; door = NULL; if (sec->specialdata) { if (!thing->player) return; door = sec->specialdata; if (door->type == sdt_openAndClose) { if (door->status == sd_waiting) door->status = sd_closing; } else return; } // Init sliding door vars if (!door) { door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0); P_AddThinker (&door->thinker); sec->specialdata = door; door->type = sdt_openAndClose; door->status = sd_opening; door->whichDoorIndex = P_FindSlidingDoorType(line); if (door->whichDoorIndex < 0) I_Error("EV_SlidingDoor: Can't use texture for sliding door!"); door->frontsector = sec; door->backsector = line->backsector; door->thinker.function = T_SlidingDoor; door->timer = SWAITTICS; door->frame = 0; door->line = line; } }
void P_SpawnGlowingLight(sector_t * sector) { glow_t *g; g = Z_Malloc(sizeof(*g), PU_LEVSPEC, 0); P_AddThinker(&g->thinker); g->sector = sector; g->minlight = P_FindMinSurroundingLight(sector, sector->lightlevel); g->maxlight = sector->lightlevel; g->thinker.function = T_Glow; g->direction = -1; sector->special = 0; }
boolean P_StartACS(int number, int map, byte * args, mobj_t * activator, line_t * line, int side) { int i; acs_t *script; int infoIndex; aste_t *statePtr; NewScript = NULL; if (map && map != gamemap) { // Add to the script store return AddToACSStore(map, number, args); } infoIndex = GetACSIndex(number); if (infoIndex == -1) { // Script not found //I_Error("P_StartACS: Unknown script number %d", number); snprintf(ErrorMsg, sizeof(ErrorMsg), "P_STARTACS ERROR: UNKNOWN SCRIPT %d", number); P_SetMessage(&players[consoleplayer], ErrorMsg, true); } statePtr = &ACSInfo[infoIndex].state; if (*statePtr == ASTE_SUSPENDED) { // Resume a suspended script *statePtr = ASTE_RUNNING; return true; } if (*statePtr != ASTE_INACTIVE) { // Script is already executing return false; } script = Z_Malloc(sizeof(acs_t), PU_LEVSPEC, 0); memset(script, 0, sizeof(acs_t)); script->number = number; script->infoIndex = infoIndex; script->activator = activator; script->line = line; script->side = side; script->ip = ACSInfo[infoIndex].address; script->thinker.function = T_InterpretACS; for (i = 0; i < ACSInfo[infoIndex].argCount; i++) { script->vars[i] = args[i]; } *statePtr = ASTE_RUNNING; P_AddThinker(&script->thinker); NewScript = script; return true; }
void P_UnArchiveThinkers(void) { byte tclass; thinker_t *currentthinker, *next; mobj_t *mobj; // // remove all the current thinkers // currentthinker = thinkercap.next; while (currentthinker != &thinkercap) { next = currentthinker->next; if (currentthinker->function == P_MobjThinker) P_RemoveMobj((mobj_t *) currentthinker); else Z_Free(currentthinker); currentthinker = next; } P_InitThinkers(); // read in saved thinkers while (1) { tclass = SV_ReadByte(); switch (tclass) { case tc_end: return; // end of list case tc_mobj: mobj = Z_Malloc(sizeof(*mobj), PU_LEVEL, NULL); saveg_read_mobj_t(mobj); mobj->target = NULL; P_SetThingPosition(mobj); mobj->info = &mobjinfo[mobj->type]; mobj->floorz = mobj->subsector->sector->floorheight; mobj->ceilingz = mobj->subsector->sector->ceilingheight; mobj->thinker.function = P_MobjThinker; P_AddThinker(&mobj->thinker); break; default: I_Error("Unknown tclass %i in savegame", tclass); } } }
static vldoor_t* get_door_block (sector_t* sec) { vldoor_t* door; door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0); P_AddThinker (&door->thinker, (actionf_p1) T_VerticalDoor); sec->ceilingdata = door; door->sector = sec; door->topwait = VDOORWAIT; door->speed = VDOORSPEED; door->direction = 1; door->line = NULL; return (door); }
//================================================================== // // Spawn a door that closes after 30 seconds // //================================================================== void P_SpawnDoorCloseIn30(sector_t * sec) { vldoor_t *door; door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0); P_AddThinker(&door->thinker); sec->specialdata = door; sec->special = 0; door->thinker.function = T_VerticalDoor; door->sector = sec; door->direction = 0; door->type = normal; door->speed = VDOORSPEED; door->topcountdown = 30 * 35; }
void P_SpawnStrobeAltFlash(sector_t* sector, int speed) { // 0x80015C44 strobe_t* flash; flash = Z_Malloc(sizeof(*flash), PU_LEVSPEC, 0); P_AddThinker(&flash->thinker); flash->sector = sector; flash->darktime = speed; flash->thinker.function.acp1 = (actionf_p1)T_StrobeFlash; flash->special = sector->special; flash->maxlight = 127; flash->brighttime = 1; flash->count = 1; }
void P_SpawnStrobeFlash(sector_t* sector, int speed) { strobe_t* flash; flash = Z_Malloc(sizeof(*flash), PU_LEVSPEC, 0); P_AddThinker(&flash->thinker); flash->sector = sector; flash->darktime = speed; flash->thinker.function.acp1 = (actionf_p1)T_StrobeFlash; flash->special = sector->special; flash->maxlight = 16; flash->brighttime = 3; flash->count = (P_Random(pr_lights) & 7) + 1; }
void P_CombineLightSpecials(sector_t *sector) { actionf_p1 func; thinker_t *thinker; combine_t *combine; switch(sector->special) { case 1: func = T_LightFlash; break; case 2: case 3: case 202: case 203: case 204: case 205: case 206: case 208: func = T_StrobeFlash; break; case 8: case 9: case 11: func = T_Glow; break; case 17: func = T_FireFlicker; break; default: return; } for(thinker = thinkercap.next; thinker != &thinkercap; thinker = thinker->next) { if((actionf_p1)func != (actionf_p1)thinker->function.acp1) { continue; } combine = Z_Malloc(sizeof(*combine), PU_LEVSPEC, 0); P_AddThinker(&combine->thinker); combine->sector = sector; combine->special = sector->special; combine->combiner = thinker; combine->func = func; combine->thinker.function.acp1 = (actionf_p1)T_Combine; return; } }
// // P_SpawnGlowingLight() // // Spawns a glowing light (smooth oscillation from min to max) thinker // // Passed the sector that spawned the thinker // Returns nothing // void P_SpawnGlowingLight(sector_t* sector) { glow_t* g; g = Z_Malloc( sizeof(*g), PU_LEVSPEC, 0); P_AddThinker(&g->thinker); g->sector = sector; g->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel); g->maxlight = sector->lightlevel; g->thinker.function.acp1 = (actionf_p1) T_Glow; g->direction = -1; sector->special &= ~31; //jff 3/14/98 clear non-generalized sector type }
static void StartOpenACS(int number, int infoIndex, int *address) { acs_t *script; script = Z_Malloc(sizeof(acs_t), PU_LEVSPEC, 0); memset(script, 0, sizeof(acs_t)); script->number = number; // World objects are allotted 1 second for initialization script->delayCount = 35; script->infoIndex = infoIndex; script->ip = address; script->thinker.function = T_InterpretACS; P_AddThinker(&script->thinker); }
//================================================================== // // P_SpawnLightFlash // // After the map has been loaded, scan each sector for specials that spawn thinkers // //================================================================== void P_SpawnLightFlash(sector_t * sector) { lightflash_t *flash; sector->special = 0; // nothing special about it during gameplay flash = Z_Malloc(sizeof(*flash), PU_LEVSPEC, 0); P_AddThinker(&flash->thinker); flash->thinker.function = T_LightFlash; flash->sector = sector; flash->maxlight = sector->lightlevel; flash->minlight = P_FindMinSurroundingLight(sector, sector->lightlevel); flash->maxtime = 64; flash->mintime = 7; flash->count = (P_Random() & flash->maxtime) + 1; }
// // P_SpawnFireFlicker // void P_SpawnFireFlicker(sector_t *sector) { fireflicker_t *flick = Z_Malloc(sizeof(*flick), PU_LEVSPEC, 0); // Note that we are resetting sector attributes. // Nothing special about it during gameplay. sector->special = 0; memset(flick, 0, sizeof(*flick)); P_AddThinker(&flick->thinker); flick->thinker.function = T_FireFlicker; flick->sector = sector; flick->maxlight = sector->lightlevel; flick->minlight = P_FindMinSurroundingLight(sector, sector->lightlevel) + 16; flick->count = 4; }
// // P_SpawnFireFlicker // // [STRIFE] // haleyjd 2011023: Changes to minimum light level and initial duration // void P_SpawnFireFlicker (sector_t* sector) { fireflicker_t* flick; // Note that we are resetting sector attributes. // Nothing special about it during gameplay. sector->special = 0; flick = Z_Malloc ( sizeof(*flick), PU_LEVSPEC, 0); P_AddThinker (&flick->thinker); flick->thinker.function.acp1 = (actionf_p1) T_FireFlicker; flick->sector = sector; flick->maxlight = sector->lightlevel; flick->minlight = sector->lightlevel - 32; // [STRIFE] changed from min surrounding+16 flick->count = 2; // [STRIFE]: Initial count 4 -> 2 }
//================================================================== // // Spawn a door that opens after 5 minutes // //================================================================== void P_SpawnDoorRaiseIn5Mins(sector_t * sec, int secnum) { vldoor_t *door; door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0); P_AddThinker(&door->thinker); sec->specialdata = door; sec->special = 0; door->thinker.function = T_VerticalDoor; door->sector = sec; door->direction = 2; door->type = raiseIn5Mins; door->speed = VDOORSPEED; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4 * FRACUNIT; door->topwait = VDOORWAIT; door->topcountdown = 5 * 60 * 35; }
// // P_SpawnFireFlicker() // // Spawns a fire flicker lighting thinker // // Passed the sector that spawned the thinker // Returns nothing // void P_SpawnFireFlicker (sector_t* sector) { fireflicker_t* flick; // Note that we are resetting sector attributes. // Nothing special about it during gameplay. sector->special &= ~31; //jff 3/14/98 clear non-generalized sector type flick = Z_Malloc ( sizeof(*flick), PU_LEVSPEC, 0); P_AddThinker (&flick->thinker); flick->thinker.function.acp1 = (actionf_p1) T_FireFlicker; flick->sector = sector; flick->maxlight = sector->lightlevel; flick->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel)+16; flick->count = 4; }
void P_SpawnFireFlicker(sector_t *sector) { fireflicker_t *flick; sector->special &= ~31; flick = Z_Malloc(sizeof(*flick), PU_LEVSPEC, 0); memset(flick, 0, sizeof(*flick)); P_AddThinker (&flick->thinker); flick->thinker.function = T_FireFlicker; flick->sector = sector; flick->maxlight = sector->lightlevel; flick->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel) + 16; flick->count = 4; }
// // Spawn a door that closes after 30 seconds // void P_SpawnDoorCloseIn30(sector_t *sec) { vldoor_t *door; door = Z_Malloc(sizeof(*door), PU_LEVSPEC, (void *)0); P_AddThinker(&door->thinker); sec->ceilingdata = door; sec->special = 0; door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor; door->sector = sec; door->direction = 0; door->type = normal; door->speed = VDOORSPEED; door->topcountdown = 30 * 35; door->line = (line_t *)0; // no line triggered us }
void P_SpawnLightFlash(sector_t *sector) { lightflash_t *flash; sector->special &= ~31; flash = Z_Malloc(sizeof(*flash), PU_LEVSPEC, 0); memset(flash, 0, sizeof(*flash)); P_AddThinker(&flash->thinker); flash->thinker.function = T_LightFlash; flash->sector = sector; flash->maxlight = sector->lightlevel; flash->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel); flash->maxtime = 64; flash->mintime = 7; flash->count = (P_Random(pr_lights)&flash->maxtime) + 1; }
// // P_SpawnLightFlash() // // Spawns a broken light flash lighting thinker // // Passed the sector that spawned the thinker // Returns nothing // void P_SpawnLightFlash (sector_t* sector) { lightflash_t* flash; // nothing special about it during gameplay sector->special &= ~31; //jff 3/14/98 clear non-generalized sector type flash = Z_Malloc ( sizeof(*flash), PU_LEVSPEC, 0); P_AddThinker (&flash->thinker); flash->thinker.function.acp1 = (actionf_p1) T_LightFlash; flash->sector = sector; flash->maxlight = sector->lightlevel; flash->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel); flash->maxtime = 64; flash->mintime = 7; flash->count = (P_Random(pr_lights)&flash->maxtime)+1; }
void P_UpdateLightThinker(light_t* destlight, light_t* srclight) { lightmorph_t* lt; lt = Z_Malloc(sizeof(*lt), PU_LEVSPEC, 0); P_AddThinker(<->thinker); lt->thinker.function.acp1 = (actionf_p1)T_LightMorph; if(destlight) { destlight->r = srclight->r; destlight->g = srclight->g; destlight->b = srclight->b; } lt->inc = 0; lt->src = srclight; // the light to morph to lt->dest = destlight == NULL ? srclight : destlight; // the light to morph from lt->r = destlight == NULL ? 0 : destlight->base_r; lt->g = destlight == NULL ? 0 : destlight->base_g; lt->b = destlight == NULL ? 0 : destlight->base_b; }
// // P_SpawnDoorCloseIn30() // // Spawn a door that closes after 30 seconds (called at level init) // // Passed the sector of the door, whose type specified the door action // Returns nothing // void P_SpawnDoorCloseIn30(sector_t *sec) { vldoor_t *door; door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0); memset(door, 0, sizeof(*door)); P_AddThinker(&door->thinker); sec->ceilingdata = door; //jff 2/22/98 sec->special = 0; door->thinker.function = T_VerticalDoor; door->sector = sec; door->direction = 0; door->type = normal; door->speed = VDOORSPEED; door->topcountdown = 30 * 35; door->line = NULL; // jff 1/31/98 remember line that triggered us door->lighttag = 0; /* killough 10/98: no lighting changes */ }
void P_SpawnPhasedLight(sector_t * sector, int base, int index) { phase_t *phase; phase = Z_Malloc(sizeof(*phase), PU_LEVSPEC, 0); P_AddThinker(&phase->thinker); phase->sector = sector; if (index == -1) { // sector->lightlevel as the index phase->index = sector->lightlevel & 63; } else { phase->index = index & 63; } phase->base = base & 255; sector->lightlevel = phase->base + PhaseTable[phase->index]; phase->thinker.function = T_Phase; sector->special = 0; }
void EV_ForceField (line_t *line, int flag) { register int i; forcefield_t *field; // find all 2s lines with same tag but force field special for (i = -1; (i = P_FindLineFromLineTag(line, i)) >= 0;) { // force field must be 2s line if (!lines[i].flags & ML_TWOSIDED) continue; // make sure force field isn't open already if (sides[lines[i].sidenum[0]].midtexture == 0) continue; // force field special? if (lines[i].special == 320) { field = Z_Malloc(sizeof(*field), PU_LEVSPEC, (void *)0); field->frontsector = lines[i].frontsector; field->backsector = lines[i].backsector; field->line = &lines[i]; field->oldflags = lines[i].flags; // used a switch? if (!flag) { field->status = ff_open; field->timer = FFWAITTICS; } // no, damaged with gun shot or deactivated with comm gadget else { field->status = ff_damaged; } P_AddThinker(&field->thinker); field->thinker.function.acv = T_ForceField; } } }
void P_SpawnGlowingLight(sector_t* sector, byte type) { glow_t* g; g = Z_Malloc(sizeof(*g), PU_LEVSPEC, 0); P_AddThinker(&g->thinker); g->count = 2; g->direction = 1; g->sector = sector; g->type = type; g->special = sector->special; g->thinker.function.acp1 = (actionf_p1)T_Glow; g->minlight = 0; if(g->type == PULSENORMAL) { g->maxlight = 32; } else if(g->type == PULSERANDOM || g->type == PULSESLOW) { g->maxlight = 48; } }
// // P_SpawnStrobeFlash // After the map has been loaded, scan each sector // for specials that spawn thinkers // void P_SpawnStrobeFlash(sector_t *sector, int fastOrSlow, int inSync) { strobe_t *flash = Z_Malloc(sizeof(*flash), PU_LEVSPEC, 0); memset(flash, 0, sizeof(*flash)); P_AddThinker(&flash->thinker); flash->sector = sector; flash->darktime = fastOrSlow; flash->brighttime = STROBEBRIGHT; flash->thinker.function = T_StrobeFlash; flash->maxlight = sector->lightlevel; flash->minlight = P_FindMinSurroundingLight(sector, sector->lightlevel); if (flash->minlight == flash->maxlight) flash->minlight = 0; // nothing special about it during gameplay sector->special = 0; flash->count = (inSync ? 1 : (P_Random() & 7) + 1); }
/** Spawns an adjustable glowing light effect in a sector. * * \param minsector Sector whose light level is used as the darkest. * \param maxsector Sector whose light level is used as the brightest, * and also the target sector for the effect. * \param length The speed of the effect. * \sa T_Glow */ glow_t *P_SpawnAdjustableGlowingLight(sector_t *minsector, sector_t *maxsector, INT32 length) { glow_t *g; P_RemoveLighting(maxsector); // out with the old, in with the new g = Z_Calloc(sizeof (*g), PU_LEVSPEC, NULL); P_AddThinker(&g->thinker); g->sector = maxsector; g->minlight = minsector->lightlevel; g->maxlight = maxsector->lightlevel; if (g->minlight > g->maxlight) { // You mixed them up, you dummy. INT32 oops = g->minlight; g->minlight = g->maxlight; g->maxlight = oops; } g->thinker.function.acp1 = (actionf_p1)T_Glow; g->direction = 1; g->speed = length/4; if (g->speed > (g->maxlight - g->minlight)/2) // don't make it ridiculous speed g->speed = (g->maxlight - g->minlight)/2; while (g->speed < 1) { if (g->minlight > 0) g->minlight--; if (g->maxlight < 255) g->maxlight++; g->speed = (g->maxlight - g->minlight)/2; } maxsector->lightingdata = g; return g; }
// // Switch force fields with id off // void EV_PlusForceField(int id, line_t *ln, mobj_t *thing, int flag) { register int line = -1; forcefield_t *field; // find all lines with id while ((line = P_FindLineFromTag(id, line)) >= 0) { // force field must be 2s line if (!lines[line].flags & ML_TWOSIDED) continue; // make sure force field isn't open already if (sides[lines[line].sidenum[0]].midtexture == 0) continue; field = Z_Malloc(sizeof(*field), PU_LEVSPEC, (void *)0); field->frontsector = lines[line].frontsector; field->backsector = lines[line].backsector; field->line = &lines[line]; field->oldflags = lines[line].flags; // used a switch? if (!flag) { field->status = ff_open; field->timer = FFWAITTICS; } // no, damaged with gun shot or deactivated with comm gadget or button else { field->status = ff_damaged; P_ChangeSwitchTexture(ln, 0); } P_AddThinker(&field->thinker); field->thinker.function.acv = T_ForceField; } }
void P_SpawnSequenceLight(sector_t* sector, dboolean first) { sequenceGlow_t* seq; sector_t *headsector = NULL; int i = 0; if(!sector->linecount) { return; } if(first) { for(i = 0; i < sector->linecount; i++) { headsector = sector->lines[i]->frontsector; if(!headsector) { // this should never happen return; } if(headsector == sector) { continue; } if(headsector->tag == sector->tag) { break; } } } seq = Z_Malloc(sizeof(*seq), PU_LEVSPEC, 0); P_AddThinker(&seq->thinker); seq->thinker.function.acp1 = (actionf_p1)T_Sequence; seq->sector = sector; seq->special = sector->special; seq->count = 1; seq->index = sector->tag; seq->start = (headsector == NULL ? 1 : 0); seq->headsector = headsector; }
/** Fades all the lights in sectors with a particular tag to a new * value. * * \param tag Tag to look for sectors by. * \param destvalue The final light value in these sectors. * \param speed Speed of the fade; the change to the ligh * level in each sector per tic. * \todo Calculate speed better so that it is possible to specify * the time for completion of the fade, and all lights fade * in this time regardless of initial values. * \sa T_LightFade */ void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed) { INT32 i; lightlevel_t *ll; sector_t *sector; // search all sectors for ones with tag for (i = -1; (i = P_FindSectorFromTag(tag, i)) >= 0 ;) { sector = §ors[i]; P_RemoveLighting(sector); // remove the old lighting effect first ll = Z_Calloc(sizeof (*ll), PU_LEVSPEC, NULL); ll->thinker.function.acp1 = (actionf_p1)T_LightFade; sector->lightingdata = ll; // set it to the lightlevel_t P_AddThinker(&ll->thinker); // add thinker ll->sector = sector; ll->destlevel = destvalue; ll->speed = speed; } }