//================================================================== // // Do Platforms // "amount" is only used for SOME platforms. // //================================================================== int EV_DoPlat(line_t * line, plattype_e type, int amount) { plat_t *plat; int secnum; int rtn; sector_t *sec; secnum = -1; rtn = 0; // // Activate all <type> plats that are in_stasis // switch (type) { case perpetualRaise: P_ActivateInStasis(line->tag); break; default: break; } while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) { sec = §ors[secnum]; if (sec->specialdata) continue; // // Find lowest & highest floors around sector // rtn = 1; plat = Z_Malloc(sizeof(*plat), PU_LEVSPEC, 0); P_AddThinker(&plat->thinker); plat->type = type; plat->sector = sec; plat->sector->specialdata = plat; plat->thinker.function = T_PlatRaise; plat->crush = false; plat->tag = line->tag; switch (type) { case raiseToNearestAndChange: plat->speed = PLATSPEED / 2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = P_FindNextHighestFloor(sec, sec->floorheight); plat->wait = 0; plat->status = up; sec->special = 0; // NO MORE DAMAGE, IF APPLICABLE S_StartSound(&sec->soundorg, sfx_stnmov); break; case raiseAndChange: plat->speed = PLATSPEED / 2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = sec->floorheight + amount * FRACUNIT; plat->wait = 0; plat->status = up; S_StartSound(&sec->soundorg, sfx_stnmov); break; case downWaitUpStay: plat->speed = PLATSPEED * 4; plat->low = P_FindLowestFloorSurrounding(sec); if (plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = sec->floorheight; plat->wait = 35 * PLATWAIT; plat->status = down; S_StartSound(&sec->soundorg, sfx_pstart); break; case perpetualRaise: plat->speed = PLATSPEED; plat->low = P_FindLowestFloorSurrounding(sec); if (plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = P_FindHighestFloorSurrounding(sec); if (plat->high < sec->floorheight) plat->high = sec->floorheight; plat->wait = 35 * PLATWAIT; plat->status = P_Random() & 1; S_StartSound(&sec->soundorg, sfx_pstart); break; } P_AddActivePlat(plat); } return rtn; }
// // P_UnArchiveSpecials // void P_UnArchiveSpecials (void) { byte tclass; ceiling_t* ceiling; vldoor_t* door; floormove_t* floor; plat_t* plat; lightflash_t* flash; strobe_t* strobe; glow_t* glow; // read in saved thinkers while (1) { tclass = *save_p++; switch (tclass) { case tc_endspecials: return; // end of list case tc_ceiling: PADSAVEP(); ceiling = (ceiling_t*)Z_Malloc (sizeof(*ceiling), PU_LEVEL, NULL); memcpy (ceiling, save_p, sizeof(*ceiling)); save_p += sizeof(*ceiling); ceiling->sector = §ors[(int)ceiling->sector]; ceiling->sector->specialdata = ceiling; if (ceiling->thinker.function.acp1) ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling; P_AddThinker (&ceiling->thinker); P_AddActiveCeiling(ceiling); break; case tc_door: PADSAVEP(); door = (vldoor_t*)Z_Malloc (sizeof(*door), PU_LEVEL, NULL); memcpy (door, save_p, sizeof(*door)); save_p += sizeof(*door); door->sector = §ors[(int)door->sector]; door->sector->specialdata = door; door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor; P_AddThinker (&door->thinker); break; case tc_floor: PADSAVEP(); floor = (floormove_t*)Z_Malloc (sizeof(*floor), PU_LEVEL, NULL); memcpy (floor, save_p, sizeof(*floor)); save_p += sizeof(*floor); floor->sector = §ors[(int)floor->sector]; floor->sector->specialdata = floor; floor->thinker.function.acp1 = (actionf_p1)T_MoveFloor; P_AddThinker (&floor->thinker); break; case tc_plat: PADSAVEP(); plat = (plat_t*)Z_Malloc (sizeof(*plat), PU_LEVEL, NULL); memcpy (plat, save_p, sizeof(*plat)); save_p += sizeof(*plat); plat->sector = §ors[(int)plat->sector]; plat->sector->specialdata = plat; if (plat->thinker.function.acp1) plat->thinker.function.acp1 = (actionf_p1)T_PlatRaise; P_AddThinker (&plat->thinker); P_AddActivePlat(plat); break; case tc_flash: PADSAVEP(); flash = (lightflash_t*)Z_Malloc (sizeof(*flash), PU_LEVEL, NULL); memcpy (flash, save_p, sizeof(*flash)); save_p += sizeof(*flash); flash->sector = §ors[(int)flash->sector]; flash->thinker.function.acp1 = (actionf_p1)T_LightFlash; P_AddThinker (&flash->thinker); break; case tc_strobe: PADSAVEP(); strobe = (strobe_t*)Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL); memcpy (strobe, save_p, sizeof(*strobe)); save_p += sizeof(*strobe); strobe->sector = §ors[(int)strobe->sector]; strobe->thinker.function.acp1 = (actionf_p1)T_StrobeFlash; P_AddThinker (&strobe->thinker); break; case tc_glow: PADSAVEP(); glow = (glow_t*)Z_Malloc (sizeof(*glow), PU_LEVEL, NULL); memcpy (glow, save_p, sizeof(*glow)); save_p += sizeof(*glow); glow->sector = §ors[(int)glow->sector]; glow->thinker.function.acp1 = (actionf_p1)T_Glow; P_AddThinker (&glow->thinker); break; default: I_Error ("P_UnarchiveSpecials:Unknown tclass %i " "in savegame",tclass); } } }
// // P_UnArchiveSpecials // void P_UnArchiveSpecials (void) { byte tclass; ceiling_t* ceiling; vldoor_t* door; floormove_t* floor; plat_t* plat; lightflash_t* flash; strobe_t* strobe; glow_t* glow; // read in saved thinkers while (1) { tclass = saveg_read8(); switch (tclass) { case tc_endspecials: return; // end of list case tc_ceiling: saveg_read_pad(); ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVEL, NULL); saveg_read_ceiling_t(ceiling); ceiling->sector->specialdata = ceiling; if (ceiling->thinker.function.acp1) ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling; P_AddThinker (&ceiling->thinker); P_AddActiveCeiling(ceiling); break; case tc_door: saveg_read_pad(); door = Z_Malloc (sizeof(*door), PU_LEVEL, NULL); saveg_read_vldoor_t(door); door->sector->specialdata = door; door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor; P_AddThinker (&door->thinker); break; case tc_floor: saveg_read_pad(); floor = Z_Malloc (sizeof(*floor), PU_LEVEL, NULL); saveg_read_floormove_t(floor); floor->sector->specialdata = floor; floor->thinker.function.acp1 = (actionf_p1)T_MoveFloor; P_AddThinker (&floor->thinker); break; case tc_plat: saveg_read_pad(); plat = Z_Malloc (sizeof(*plat), PU_LEVEL, NULL); saveg_read_plat_t(plat); plat->sector->specialdata = plat; if (plat->thinker.function.acp1) plat->thinker.function.acp1 = (actionf_p1)T_PlatRaise; P_AddThinker (&plat->thinker); P_AddActivePlat(plat); break; case tc_flash: saveg_read_pad(); flash = Z_Malloc (sizeof(*flash), PU_LEVEL, NULL); saveg_read_lightflash_t(flash); flash->thinker.function.acp1 = (actionf_p1)T_LightFlash; P_AddThinker (&flash->thinker); break; case tc_strobe: saveg_read_pad(); strobe = Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL); saveg_read_strobe_t(strobe); strobe->thinker.function.acp1 = (actionf_p1)T_StrobeFlash; P_AddThinker (&strobe->thinker); break; case tc_glow: saveg_read_pad(); glow = Z_Malloc (sizeof(*glow), PU_LEVEL, NULL); saveg_read_glow_t(glow); glow->thinker.function.acp1 = (actionf_p1)T_Glow; P_AddThinker (&glow->thinker); break; default: I_Error ("P_UnarchiveSpecials:Unknown tclass %i " "in savegame",tclass); } } }
// // EV_DoPlat // // Handle Plat linedef types // // Passed the linedef that activated the plat, the type of plat action, // and for some plat types, an amount to raise // Returns true if a thinker is started, or restarted from stasis // int EV_DoPlat ( line_t* line, plattype_e type, int amount ) { plat_t* plat; int secnum; int rtn; sector_t* sec; secnum = -1; rtn = 0; // Activate all <type> plats that are in_stasis switch(type) { case perpetualRaise: P_ActivateInStasis(line->tag); break; case toggleUpDn: P_ActivateInStasis(line->tag); rtn=1; break; default: break; } // act on all sectors tagged the same as the activating linedef while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; // don't start a second floor function if already moving if (P_SectorActive(floor_special,sec)) //jff 2/23/98 multiple thinkers continue; // Create a thinker rtn = 1; plat = Z_Malloc( sizeof(*plat), PU_LEVSPEC, 0); memset(plat, 0, sizeof(*plat)); P_AddThinker(&plat->thinker); plat->type = type; plat->sector = sec; plat->sector->floordata = plat; //jff 2/23/98 multiple thinkers plat->thinker.function = T_PlatRaise; plat->crush = false; plat->tag = line->tag; //jff 1/26/98 Avoid raise plat bouncing a head off a ceiling and then //going down forever -- default low to plat height when triggered plat->low = sec->floorheight; // set up plat according to type switch(type) { case raiseToNearestAndChange: plat->speed = PLATSPEED/2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = P_FindNextHighestFloor(sec,sec->floorheight); plat->wait = 0; plat->status = up; sec->special = 0; //jff 3/14/98 clear old field as well sec->oldspecial = 0; S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov); break; case raiseAndChange: plat->speed = PLATSPEED/2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = sec->floorheight + amount*FRACUNIT; plat->wait = 0; plat->status = up; S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov); break; case downWaitUpStay: plat->speed = PLATSPEED * 4; plat->low = P_FindLowestFloorSurrounding(sec); if (plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = sec->floorheight; plat->wait = 35*PLATWAIT; plat->status = down; S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart); break; case blazeDWUS: plat->speed = PLATSPEED * 8; plat->low = P_FindLowestFloorSurrounding(sec); if (plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = sec->floorheight; plat->wait = 35*PLATWAIT; plat->status = down; S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart); break; case perpetualRaise: plat->speed = PLATSPEED; plat->low = P_FindLowestFloorSurrounding(sec); if (plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = P_FindHighestFloorSurrounding(sec); if (plat->high < sec->floorheight) plat->high = sec->floorheight; plat->wait = 35*PLATWAIT; plat->status = P_Random(pr_plats)&1; S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart); break; case toggleUpDn: //jff 3/14/98 add new type to support instant toggle plat->speed = PLATSPEED; //not used plat->wait = 35*PLATWAIT; //not used plat->crush = true; //jff 3/14/98 crush anything in the way // set up toggling between ceiling, floor inclusive plat->low = sec->ceilingheight; plat->high = sec->floorheight; plat->status = down; break; default: break; } P_AddActivePlat(plat); // add plat to list of active plats } return rtn; }
// // P_UnArchiveSpecials // void P_UnArchiveSpecials(void) { // read in saved thinkers while (true) { byte tclass = saveg_read8(); switch (tclass) { case tc_endspecials: // end of list return; case tc_ceiling: { ceiling_t *ceiling = Z_Malloc(sizeof(*ceiling), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_ceiling_t(ceiling); ceiling->sector->ceilingdata = ceiling; ceiling->thinker.function = T_MoveCeiling; P_AddThinker(&ceiling->thinker); P_AddActiveCeiling(ceiling); break; } case tc_door: { vldoor_t *door = Z_Malloc(sizeof(*door), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_vldoor_t(door); door->sector->ceilingdata = door; door->thinker.function = T_VerticalDoor; P_AddThinker(&door->thinker); break; } case tc_floor: { floormove_t *floor = Z_Malloc(sizeof(*floor), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_floormove_t(floor); floor->sector->floordata = floor; floor->thinker.function = T_MoveFloor; P_AddThinker(&floor->thinker); break; } case tc_plat: { plat_t *plat = Z_Malloc(sizeof(*plat), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_plat_t(plat); plat->sector->floordata = plat; P_AddThinker(&plat->thinker); P_AddActivePlat(plat); break; } case tc_flash: { lightflash_t *flash = Z_Malloc(sizeof(*flash), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_lightflash_t(flash); flash->thinker.function = T_LightFlash; P_AddThinker(&flash->thinker); break; } case tc_strobe: { strobe_t *strobe = Z_Malloc(sizeof(*strobe), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_strobe_t(strobe); strobe->thinker.function = T_StrobeFlash; P_AddThinker(&strobe->thinker); break; } case tc_glow: { glow_t *glow = Z_Malloc(sizeof(*glow), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_glow_t(glow); glow->thinker.function = T_Glow; P_AddThinker(&glow->thinker); break; } case tc_fireflicker: { fireflicker_t *fireflicker = Z_Malloc(sizeof(*fireflicker), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_fireflicker_t(fireflicker); fireflicker->thinker.function = T_FireFlicker; P_AddThinker(&fireflicker->thinker); break; } case tc_elevator: { elevator_t *elevator = Z_Malloc(sizeof(*elevator), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_elevator_t(elevator); elevator->sector->ceilingdata = elevator; elevator->thinker.function = T_MoveElevator; P_AddThinker(&elevator->thinker); break; } case tc_scroll: { scroll_t *scroll = Z_Malloc(sizeof(*scroll), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_scroll_t(scroll); scroll->thinker.function = T_Scroll; P_AddThinker(&scroll->thinker); break; } case tc_pusher: { pusher_t *pusher = Z_Malloc(sizeof(*pusher), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_pusher_t(pusher); pusher->thinker.function = T_Pusher; pusher->source = P_GetPushThing(pusher->affectee); P_AddThinker(&pusher->thinker); break; } case tc_button: { button_t *button = Z_Malloc(sizeof(*button), PU_LEVEL, NULL); saveg_read_pad(); saveg_read_button_t(button); P_StartButton(button->line, button->where, button->btexture, button->btimer); break; } default: I_Error("This savegame is invalid."); } } }
void P_UnArchiveSpecials(void) { byte tclass; ceiling_t *ceiling; vldoor_t *door; floormove_t *floor; plat_t *plat; lightflash_t *flash; strobe_t *strobe; glow_t *glow; // read in saved thinkers while (1) { tclass = SV_ReadByte(); switch (tclass) { case tc_endspecials: return; // end of list case tc_ceiling: ceiling = Z_Malloc(sizeof(*ceiling), PU_LEVEL, NULL); saveg_read_ceiling_t(ceiling); ceiling->sector->specialdata = T_MoveCeiling; // ??? ceiling->thinker.function = T_MoveCeiling; P_AddThinker(&ceiling->thinker); P_AddActiveCeiling(ceiling); break; case tc_door: door = Z_Malloc(sizeof(*door), PU_LEVEL, NULL); saveg_read_vldoor_t(door); door->sector->specialdata = door; door->thinker.function = T_VerticalDoor; P_AddThinker(&door->thinker); break; case tc_floor: floor = Z_Malloc(sizeof(*floor), PU_LEVEL, NULL); saveg_read_floormove_t(floor); floor->sector->specialdata = T_MoveFloor; floor->thinker.function = T_MoveFloor; P_AddThinker(&floor->thinker); break; case tc_plat: plat = Z_Malloc(sizeof(*plat), PU_LEVEL, NULL); saveg_read_plat_t(plat); plat->sector->specialdata = T_PlatRaise; // In the original Heretic code this was a conditional "fix" // of the thinker function, but the save code (above) decides // whether to save a T_PlatRaise based on thinker function // anyway, so it can't be NULL. Having the conditional causes // a bug, as our saveg_read_thinker_t sets these to NULL. // if (plat->thinker.function) plat->thinker.function = T_PlatRaise; P_AddThinker(&plat->thinker); P_AddActivePlat(plat); break; case tc_flash: flash = Z_Malloc(sizeof(*flash), PU_LEVEL, NULL); saveg_read_lightflash_t(flash); flash->thinker.function = T_LightFlash; P_AddThinker(&flash->thinker); break; case tc_strobe: strobe = Z_Malloc(sizeof(*strobe), PU_LEVEL, NULL); saveg_read_strobe_t(strobe); strobe->thinker.function = T_StrobeFlash; P_AddThinker(&strobe->thinker); break; case tc_glow: glow = Z_Malloc(sizeof(*glow), PU_LEVEL, NULL); saveg_read_glow_t(glow); glow->thinker.function = T_Glow; P_AddThinker(&glow->thinker); break; default: I_Error("P_UnarchiveSpecials:Unknown tclass %i " "in savegame", tclass); } } }
// // Do Platforms // "amount" is only used for SOME platforms. // dboolean EV_DoPlat(line_t *line, plattype_e type, int amount) { plat_t *plat; int secnum = -1; dboolean rtn = false; sector_t *sec = NULL; // Activate all <type> plats that are in_stasis switch (type) { case perpetualRaise: P_ActivateInStasis(line->tag); break; case toggleUpDn: P_ActivateInStasis(line->tag); rtn = true; break; default: break; } while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0) { sec = sectors + secnum; if (P_SectorActive(floor_special, sec)) continue; // Find lowest & highest floors around sector rtn = true; plat = Z_Calloc(1, sizeof(*plat), PU_LEVSPEC, NULL); P_AddThinker(&plat->thinker); plat->type = type; plat->sector = sec; plat->sector->floordata = plat; plat->thinker.function = T_PlatRaise; plat->tag = line->tag; plat->low = sec->floorheight; switch (type) { case raiseToNearestAndChange: plat->speed = PLATSPEED / 2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = P_FindNextHighestFloor(sec, sec->floorheight); plat->status = up; sec->special = 0; S_StartSectorSound(&sec->soundorg, sfx_stnmov); break; case raiseAndChange: plat->speed = PLATSPEED / 2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = sec->floorheight + amount * FRACUNIT; plat->status = up; S_StartSectorSound(&sec->soundorg, sfx_stnmov); break; case downWaitUpStay: plat->speed = PLATSPEED * 4; plat->low = MIN(P_FindLowestFloorSurrounding(sec), sec->floorheight); plat->high = sec->floorheight; plat->wait = TICRATE * PLATWAIT; plat->status = down; S_StartSectorSound(&sec->soundorg, sfx_pstart); break; case blazeDWUS: plat->speed = PLATSPEED * 8; plat->low = MIN(P_FindLowestFloorSurrounding(sec), sec->floorheight); plat->high = sec->floorheight; plat->wait = TICRATE * PLATWAIT; plat->status = down; S_StartSectorSound(&sec->soundorg, sfx_pstart); break; case perpetualRaise: plat->speed = PLATSPEED; plat->low = MIN(P_FindLowestFloorSurrounding(sec), sec->floorheight); plat->high = MAX(sec->floorheight, P_FindHighestFloorSurrounding(sec)); plat->wait = TICRATE * PLATWAIT; plat->status = (plat_e)(M_Random() & 1); S_StartSectorSound(&sec->soundorg, sfx_pstart); break; case toggleUpDn: // jff 3/14/98 add new type to support instant toggle plat->speed = PLATSPEED; // not used plat->wait = TICRATE * PLATWAIT; // not used plat->crush = true; // jff 3/14/98 crush anything in the way // set up toggling between ceiling, floor inclusive plat->low = sec->ceilingheight; plat->high = sec->floorheight; plat->status = down; break; default: break; } P_AddActivePlat(plat); } if (sec) for (int i = 0; i < sec->linecount; i++) sec->lines[i]->flags &= ~ML_SECRET; return rtn; }
// // P_UnArchiveSpecials // void P_UnArchiveSpecials (void) { byte tclass; // read in saved thinkers while ((tclass = *save_p++) != tc_endspecials) // killough 2/14/98 switch (tclass) { case tc_ceiling: PADSAVEP(); { ceiling_t *ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVEL, NULL); memcpy (ceiling, save_p, sizeof(*ceiling)); save_p += sizeof(*ceiling); ceiling->sector = §ors[(int)ceiling->sector]; ceiling->sector->ceilingdata = ceiling; //jff 2/22/98 if (ceiling->thinker.function) ceiling->thinker.function = T_MoveCeiling; P_AddThinker (&ceiling->thinker); P_AddActiveCeiling(ceiling); break; } case tc_door: PADSAVEP(); { vldoor_t *door = Z_Malloc (sizeof(*door), PU_LEVEL, NULL); memcpy (door, save_p, sizeof(*door)); save_p += sizeof(*door); door->sector = §ors[(int)door->sector]; //jff 1/31/98 unarchive line remembered by door as well door->line = (int)door->line!=-1? &lines[(int)door->line] : NULL; door->sector->ceilingdata = door; //jff 2/22/98 door->thinker.function = T_VerticalDoor; P_AddThinker (&door->thinker); break; } case tc_floor: PADSAVEP(); { floormove_t *floor = Z_Malloc (sizeof(*floor), PU_LEVEL, NULL); memcpy (floor, save_p, sizeof(*floor)); save_p += sizeof(*floor); floor->sector = §ors[(int)floor->sector]; floor->sector->floordata = floor; //jff 2/22/98 floor->thinker.function = T_MoveFloor; P_AddThinker (&floor->thinker); break; } case tc_plat: PADSAVEP(); { plat_t *plat = Z_Malloc (sizeof(*plat), PU_LEVEL, NULL); memcpy (plat, save_p, sizeof(*plat)); save_p += sizeof(*plat); plat->sector = §ors[(int)plat->sector]; plat->sector->floordata = plat; //jff 2/22/98 if (plat->thinker.function) plat->thinker.function = T_PlatRaise; P_AddThinker (&plat->thinker); P_AddActivePlat(plat); break; } case tc_flash: PADSAVEP(); { lightflash_t *flash = Z_Malloc (sizeof(*flash), PU_LEVEL, NULL); memcpy (flash, save_p, sizeof(*flash)); save_p += sizeof(*flash); flash->sector = §ors[(int)flash->sector]; flash->thinker.function = T_LightFlash; P_AddThinker (&flash->thinker); break; } case tc_strobe: PADSAVEP(); { strobe_t *strobe = Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL); memcpy (strobe, save_p, sizeof(*strobe)); save_p += sizeof(*strobe); strobe->sector = §ors[(int)strobe->sector]; strobe->thinker.function = T_StrobeFlash; P_AddThinker (&strobe->thinker); break; } case tc_glow: PADSAVEP(); { glow_t *glow = Z_Malloc (sizeof(*glow), PU_LEVEL, NULL); memcpy (glow, save_p, sizeof(*glow)); save_p += sizeof(*glow); glow->sector = §ors[(int)glow->sector]; glow->thinker.function = T_Glow; P_AddThinker (&glow->thinker); break; } case tc_flicker: // killough 10/4/98 PADSAVEP(); { fireflicker_t *flicker = Z_Malloc (sizeof(*flicker), PU_LEVEL, NULL); memcpy (flicker, save_p, sizeof(*flicker)); save_p += sizeof(*flicker); flicker->sector = §ors[(int)flicker->sector]; flicker->thinker.function = T_FireFlicker; P_AddThinker (&flicker->thinker); break; } //jff 2/22/98 new case for elevators case tc_elevator: PADSAVEP(); { elevator_t *elevator = Z_Malloc (sizeof(*elevator), PU_LEVEL, NULL); memcpy (elevator, save_p, sizeof(*elevator)); save_p += sizeof(*elevator); elevator->sector = §ors[(int)elevator->sector]; elevator->sector->floordata = elevator; //jff 2/22/98 elevator->sector->ceilingdata = elevator; //jff 2/22/98 elevator->thinker.function = T_MoveElevator; P_AddThinker (&elevator->thinker); break; } case tc_scroll: // killough 3/7/98: scroll effect thinkers { scroll_t *scroll = Z_Malloc (sizeof(scroll_t), PU_LEVEL, NULL); memcpy (scroll, save_p, sizeof(scroll_t)); save_p += sizeof(scroll_t); scroll->thinker.function = T_Scroll; P_AddThinker(&scroll->thinker); break; } case tc_pusher: // phares 3/22/98: new Push/Pull effect thinkers { pusher_t *pusher = Z_Malloc (sizeof(pusher_t), PU_LEVEL, NULL); memcpy (pusher, save_p, sizeof(pusher_t)); save_p += sizeof(pusher_t); pusher->thinker.function = T_Pusher; pusher->source = P_GetPushThing(pusher->affectee); P_AddThinker(&pusher->thinker); break; } default: I_Error("P_UnarchiveSpecials: Unknown tclass %i in savegame", tclass); } }
void P_UnArchiveSpecials(void) { int i; dboolean specialthinker; byte tclass; void* thinker; thinker_t* currentthinker; thinker_t* next; // remove all the current thinkers currentthinker = thinkercap.next; while(currentthinker != &thinkercap) { next = currentthinker->next; Z_Free(currentthinker); currentthinker = next; } thinkercap.prev = thinkercap.next = &thinkercap; while(1) { tclass = saveg_read8(); if(tclass == tc_endthinkers) { return; } if(tclass > tc_endthinkers) { I_Error("P_UnarchiveSpecials: Unknown tclass %i in savegame", tclass); } for(i = 0; saveg_specials[i].type != tc_endthinkers; i++) { if(tclass == saveg_specials[i].type) { saveg_read_pad(); thinker = Z_Malloc(saveg_specials[i].structsize, PU_LEVEL, NULL); saveg_specials[i].readfunc(thinker); ((thinker_t*)thinker)->function.acp1 = (actionf_p1)saveg_specials[i].function.acp1; P_AddThinker(thinker); // handle special cases switch(tclass) { case tc_ceiling: specialthinker = saveg_read32(); if(!specialthinker) { ((thinker_t*)thinker)->function.acp1 = NULL; } P_AddActiveCeiling(thinker); break; case tc_plat: specialthinker = saveg_read32(); if(!specialthinker) { ((thinker_t*)thinker)->function.acp1 = NULL; } P_AddActivePlat(thinker); break; case tc_combine: P_CombineLightSpecials(((combine_t*)thinker)->sector); P_RemoveThinker(thinker); break; } if(((thinker_t*)thinker)->function.acp1 != NULL) { specialthinker = saveg_read32(); if(specialthinker) { macrothinker = (thinker_t*)thinker; } } break; } } } }
// // EV_DoPlat // // Do Platforms "amount" is only used for SOME platforms. // int EV_DoPlat(line_t* line, plattype_e type, int amount) { plat_t* plat; int secnum; int rtn; sector_t* sec; secnum = -1; rtn = 0; // Activate all <type> plats that are in_stasis switch(type) { case perpetualRaise: P_ActivateInStasis(line->tag); break; default: break; } while((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; if (sec->specialdata) continue; // Find lowest & highest floors around sector rtn = 1; plat = Z_Malloc( sizeof(*plat), PU_LEVSPEC, 0); P_AddThinker(&plat->thinker); plat->type = type; plat->sector = sec; plat->sector->specialdata = plat; plat->thinker.function.acp1 = (actionf_p1) T_PlatRaise; plat->crush = false; plat->tag = line->tag; // haleyjd 20141001 [SVE]: protect against uninitialized plat->low // causing bounced plats that descend forever plat->low = sec->floorheight; switch(type) { case raiseToNearestAndChange: plat->speed = PLATSPEED/2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = P_FindNextHighestFloor(sec,sec->floorheight); plat->wait = 0; plat->status = up; // NO MORE DAMAGE, IF APPLICABLE sec->special = 0; S_StartSound(&sec->soundorg, sfx_stnmov); break; case raiseAndChange: plat->speed = PLATSPEED/2; sec->floorpic = sides[line->sidenum[0]].sector->floorpic; plat->high = sec->floorheight + amount * FRACUNIT; plat->wait = 0; plat->status = up; S_StartSound(&sec->soundorg, sfx_stnmov); break; // villsa [STRIFE] case upWaitDownStay: plat->speed = PLATSPEED * 4; plat->high = P_FindNextHighestFloor(sec, sec->floorheight); plat->low = sec->floorheight; plat->wait = TICRATE * PLATWAIT; plat->status = up; S_StartSound(&sec->soundorg, sfx_pstart); break; case downWaitUpStay: plat->speed = PLATSPEED * 4; plat->low = P_FindLowestFloorSurrounding(sec); if(plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = sec->floorheight; plat->wait = TICRATE * PLATWAIT; plat->status = down; S_StartSound(&sec->soundorg, sfx_pstart); break; // villsa [STRIFE] case slowDWUS: plat->speed = PLATSPEED; plat->low = P_FindLowestFloorSurrounding(sec); if(plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = sec->floorheight; plat->wait = TICRATE * (PLATWAIT * 10); plat->status = down; S_StartSound(&sec->soundorg,sfx_pstart); break; case blazeDWUS: plat->speed = PLATSPEED * 8; plat->low = P_FindLowestFloorSurrounding(sec); if(plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = sec->floorheight; plat->wait = TICRATE * PLATWAIT; plat->status = down; S_StartSound(&sec->soundorg, sfx_pstart); break; case perpetualRaise: plat->speed = PLATSPEED; plat->low = P_FindLowestFloorSurrounding(sec); if(plat->low > sec->floorheight) plat->low = sec->floorheight; plat->high = P_FindHighestFloorSurrounding(sec); if(plat->high < sec->floorheight) plat->high = sec->floorheight; plat->wait = TICRATE * PLATWAIT; plat->status = P_Random() & 1; S_StartSound(&sec->soundorg, sfx_pstart); break; } P_AddActivePlat(plat); } return rtn; }