예제 #1
0
파일: p_plats.c 프로젝트: Krazygamr/D-Touch
//==================================================================
//
//      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 = &sectors[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;
}
예제 #2
0
//
// 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 = &sectors[(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 = &sectors[(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 = &sectors[(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 = &sectors[(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 = &sectors[(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 = &sectors[(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 = &sectors[(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);
	}
	
    }

}
예제 #3
0
//
// 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);
	}
	
    }

}
예제 #4
0
//
// 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 = &sectors[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;
}
예제 #5
0
//
// 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.");
        }
    }
}
예제 #6
0
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);
        }

    }

}
예제 #7
0
//
// 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;
}
예제 #8
0
파일: p_saveg.c 프로젝트: Krazygamr/D-Touch
//
// 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 = &sectors[(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 = &sectors[(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 = &sectors[(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 = &sectors[(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 = &sectors[(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 = &sectors[(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 = &sectors[(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 = &sectors[(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 = &sectors[(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);
      }
}
예제 #9
0
파일: p_saveg.c 프로젝트: directhex/doom64
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;
            }
        }
    }
}
예제 #10
0
//
// 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 = &sectors[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;
}