Beispiel #1
0
//
// CeilingThinker::serialize
//
// Saves and loads CeilingThinker thinkers.
//
void CeilingThinker::serialize(SaveArchive &arc)
{
   Super::serialize(arc);

   arc << type << bottomheight << topheight << speed << oldspeed
       << crush << special << texture << direction << inStasis << tag 
       << olddirection;

   // Reattach to active ceilings list
   if(arc.isLoading())
      P_AddActiveCeiling(this);
}
Beispiel #2
0
//
// EV_DoCeiling
// Move a ceiling up/down and all around!
//
int
EV_DoCeiling
( line_t*		line,
  ceiling_e		type )
{
	int			secnum;
	int			rtn;
	sector_t*	sec;
	ceiling_t*	ceiling;
		
	secnum = -1;
	rtn = 0;
	
	//	Reactivate in-stasis ceilings...for certain types.
	switch(type)
	{
	  case fastCrushAndRaise:
	  case silentCrushAndRaise:
	  case crushAndRaise:
		P_ActivateInStasisCeiling(line);
	  default:
		break;
	}
		
	while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
	{
		sec = &sectors[secnum];
		if (sec->specialdata)
			continue;
		
		// new door thinker
		rtn = 1;
		ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVSPEC, 0);
		P_AddThinker (&ceiling->thinker);
		sec->specialdata = ceiling;
		ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling;
		ceiling->sector = sec;
		ceiling->crush = false;
		
		switch(type)
		{
		  case fastCrushAndRaise:
			ceiling->crush = true;
			ceiling->topheight = sec->ceilingheight;
			ceiling->bottomheight = sec->floorheight + (8*FRACUNIT);
			ceiling->direction = -1;
			ceiling->speed = CEILSPEED * 2;
			break;

		  case silentCrushAndRaise:
		  case crushAndRaise:
			ceiling->crush = true;
			ceiling->topheight = sec->ceilingheight;
		  case lowerAndCrush:
		  case lowerToFloor:
			ceiling->bottomheight = sec->floorheight;
			if (type != lowerToFloor)
				ceiling->bottomheight += 8*FRACUNIT;
			ceiling->direction = -1;
			ceiling->speed = CEILSPEED;
			break;

		  case raiseToHighest:
			ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
			ceiling->direction = 1;
			ceiling->speed = CEILSPEED;
			break;
		}
				
		ceiling->tag = sec->tag;
		ceiling->type = type;
		P_AddActiveCeiling(ceiling);
	}
	return rtn;
}
Beispiel #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);
	}
	
    }

}
Beispiel #4
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);
	}
	
    }

}
Beispiel #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.");
        }
    }
}
Beispiel #6
0
//
// EV_DoCeiling
//
// Move a ceiling up/down or start a crusher
//
// Passed the linedef activating the function and the type of function desired
// returns true if a thinker started
//
int EV_DoCeiling
(line_t* line,
 ceiling_e type)
{
  int   secnum;
  int   rtn;
  sector_t* sec;
  ceiling_t*  ceiling;

  secnum = -1;
  rtn = 0;

  // Reactivate in-stasis ceilings...for certain types.
  // This restarts a crusher after it has been stopped
  switch (type)
  {
  case fastCrushAndRaise:
  case silentCrushAndRaise:
  case crushAndRaise:
    //jff 4/5/98 return if activated
    rtn = P_ActivateInStasisCeiling(line);
  default:
    break;
  }

  // affects all sectors with the same tag as the linedef
  while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0)
  {
    sec = &sectors[secnum];

    // if ceiling already moving, don't start a second function on it
    if (P_SectorActive(ceiling_special, sec)) //jff 2/22/98
      continue;

    // create a new ceiling thinker
    rtn = 1;
    ceiling = Z_Malloc(sizeof(*ceiling), PU_LEVSPEC, 0);
    P_AddThinker(&ceiling->thinker);
    sec->ceilingdata = ceiling;               //jff 2/22/98
    ceiling->thinker.function = T_MoveCeiling;
    ceiling->sector = sec;
    ceiling->crush = false;

    // setup ceiling structure according to type of function
    switch (type)
    {
    case fastCrushAndRaise:
      ceiling->crush = true;
      ceiling->topheight = sec->ceilingheight;
      ceiling->bottomheight = sec->floorheight + (8 * FRACUNIT);
      ceiling->direction = -1;
      ceiling->speed = CEILSPEED * 2;
      break;

    case silentCrushAndRaise:
    case crushAndRaise:
      ceiling->crush = true;
      ceiling->topheight = sec->ceilingheight;
    case lowerAndCrush:
    case lowerToFloor:
      ceiling->bottomheight = sec->floorheight;
      if (type != lowerToFloor)
        ceiling->bottomheight += 8 * FRACUNIT;
      ceiling->direction = -1;
      ceiling->speed = CEILSPEED;
      break;

    case raiseToHighest:
      ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
      ceiling->direction = 1;
      ceiling->speed = CEILSPEED;
      break;

    case lowerToLowest:
      ceiling->bottomheight = P_FindLowestCeilingSurrounding(sec);
      ceiling->direction = -1;
      ceiling->speed = CEILSPEED;
      break;

    case lowerToMaxFloor:
      ceiling->bottomheight = P_FindHighestFloorSurrounding(sec);
      ceiling->direction = -1;
      ceiling->speed = CEILSPEED;
      break;

    default:
      break;
    }

    // add the ceiling to the active list
    ceiling->tag = sec->tag;
    ceiling->type = type;
    P_AddActiveCeiling(ceiling);
  }
  return rtn;
}
Beispiel #7
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);
        }

    }

}
Beispiel #8
0
//
// 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);
      }
}
Beispiel #9
0
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;
            }
        }
    }
}
Beispiel #10
0
//
// EV_DoCeiling
// Move a ceiling up/down and all around!
//
// haleyjd 10/04/10: [STRIFE] Changes:
// * Fast crushers were made 2x as fast.
// * lowerAndCrush was apparently "fixed" to actually crush, and was also
//   altered to lower all the way to the floor rather than remain 8 above.
// * silentCrushAndRaise and crushAndRaise no longer crush.
int
EV_DoCeiling
( line_t*       line,
  ceiling_e     type )
{
    int         secnum;
    int         rtn;
    sector_t*   sec;
    ceiling_t*  ceiling;

    secnum = -1;
    rtn = 0;

    //	Reactivate in-stasis ceilings...for certain types.
    switch(type)
    {
    case fastCrushAndRaise:
    case silentCrushAndRaise:
    case crushAndRaise:
        P_ActivateInStasisCeiling(line);
    default:
        break;
    }

    while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
    {
        sec = &sectors[secnum];
        if (sec->specialdata)
            continue;

        // new door thinker
        rtn = 1;
        ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVSPEC, 0);
        P_AddThinker (&ceiling->thinker);
        sec->specialdata = ceiling;
        ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling;
        ceiling->sector = sec;
        ceiling->crush = false;

        switch(type)
        {
        case fastCrushAndRaise:
            // [STRIFE]: Speed of fast crushers increased by 2x!
            ceiling->crush = true;
            ceiling->topheight = sec->ceilingheight;
            ceiling->bottomheight = sec->floorheight + (8*FRACUNIT);
            ceiling->direction = -1;
            ceiling->speed = CEILSPEED * 4; // [STRIFE] Was CEILSPEED * 2
            break;

        case lowerAndCrush:
            // [STRIFE] lowerAndCrush doesn't seem to have crushed in DOOM,
            // but it was certainly made to do so in Strife! It is also
            // changed to lower all the way to the floor.
            ceiling->crush = 1;
            ceiling->direction = -1;
            ceiling->speed = CEILSPEED;
            ceiling->bottomheight = sec->floorheight;
            break;

        case silentCrushAndRaise:
        case crushAndRaise:
            // [STRIFE] haleyjd 20130209: Turns out these types do NOT crush
            // in Strife... yeah, that makes a lot of sense. Thanks to Gez for
            // having detected this difference.
            //ceiling->crush = true;
            ceiling->topheight = sec->ceilingheight;

        case lowerToFloor:
            ceiling->bottomheight = sec->floorheight;
            if (type != lowerToFloor)
                ceiling->bottomheight += 8*FRACUNIT;
            ceiling->direction = -1;
            ceiling->speed = CEILSPEED;
            break;

        case raiseToHighest:
            ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
            ceiling->direction = 1;
            ceiling->speed = CEILSPEED;
            break;
        }

        ceiling->tag = sec->tag;
        ceiling->type = type;
        P_AddActiveCeiling(ceiling);
    }
    return rtn;
}
Beispiel #11
0
//
// EV_DoCeiling
//
// Move a ceiling up/down or start a crusher
//
// Passed the linedef activating the function and the type of function desired
// returns true if a thinker started
//
int EV_DoCeiling(const line_t *line, ceiling_e type)
{
   int       secnum = -1;
   int       rtn = 0;
   int       noise = CNOISE_NORMAL; // haleyjd 09/28/06
   sector_t  *sec;
   CeilingThinker *ceiling;
      
   // Reactivate in-stasis ceilings...for certain types.
   // This restarts a crusher after it has been stopped
   switch(type)
   {
   case fastCrushAndRaise:
   case silentCrushAndRaise:
   case crushAndRaise:
      //jff 4/5/98 return if activated
      rtn = P_ActivateInStasisCeiling(line, line->tag);
   default:
      break;
   }
  
   // affects all sectors with the same tag as the linedef
   while((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
   {
      sec = &sectors[secnum];
      
      // if ceiling already moving, don't start a second function on it
      if(P_SectorActive(ceiling_special, sec))  //jff 2/22/98
         continue;
  
      // create a new ceiling thinker
      rtn = 1;
      ceiling = new CeilingThinker;
      ceiling->addThinker();
      sec->ceilingdata = ceiling;               //jff 2/22/98
      ceiling->sector = sec;
      ceiling->crush = -1;
      ceiling->crushflags = 0;   // ioanch 20160305
  
      // setup ceiling structure according to type of function
      switch(type)
      {
      case fastCrushAndRaise:
         ceiling->crush = 10;
         ceiling->topheight = sec->ceilingheight;
         ceiling->bottomheight = sec->floorheight + (8*FRACUNIT);
         ceiling->direction = plat_down;
         ceiling->speed = CEILSPEED * 2;
         break;

      case silentCrushAndRaise:
         noise = CNOISE_SEMISILENT;
      case crushAndRaise:
         ceiling->crush = 10;
         ceiling->topheight = sec->ceilingheight;
      case lowerAndCrush:
      case lowerToFloor:
         ceiling->bottomheight = sec->floorheight;
         if(type != lowerToFloor)
            ceiling->bottomheight += 8*FRACUNIT;
         ceiling->direction = plat_down;
         ceiling->speed = CEILSPEED;
         break;

      case raiseToHighest:
         ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
         ceiling->direction = plat_up;
         ceiling->speed = CEILSPEED;
         break;
         
      case lowerToLowest:
         ceiling->bottomheight = P_FindLowestCeilingSurrounding(sec);
         ceiling->direction = plat_down;
         ceiling->speed = CEILSPEED;
         break;
         
      case lowerToMaxFloor:
         ceiling->bottomheight = P_FindHighestFloorSurrounding(sec);
         ceiling->direction = plat_down;
         ceiling->speed = CEILSPEED;
         break;
         
      default:
         break;
      }
    
      // add the ceiling to the active list
      ceiling->tag = sec->tag;
      ceiling->type = type;
      P_AddActiveCeiling(ceiling);

      // haleyjd 09/28/06: sound sequences
      P_CeilingSequence(ceiling->sector, noise);
   }
   return rtn;
}
Beispiel #12
0
//==================================================================
//
//              EV_DoCeiling
//              Move a ceiling up/down and all around!
//
//==================================================================
int EV_DoCeiling(line_t *line, byte *arg, ceiling_e type)
{
	int     secnum, rtn;
	sector_t *sec;
	ceiling_t *ceiling;

	secnum = -1;
	rtn = 0;

	/* Old Ceiling stasis code
	   //
	   //      Reactivate in-stasis ceilings...for certain types.
	   //
	   switch(type)
	   {
	   case CLEV_CRUSHANDRAISE:
	   P_ActivateInStasisCeiling(line);
	   default:
	   break;
	   }
	 */
	while((secnum = P_FindSectorFromTag(arg[0], secnum)) >= 0)
	{
		sec = &sectors[secnum];
		if(sec->specialdata)
			continue;

		//
		// new door thinker
		//
		rtn = 1;
		ceiling = Z_Malloc(sizeof(*ceiling), PU_LEVSPEC, 0);
		P_AddThinker(&ceiling->thinker);
		sec->specialdata = ceiling;
		ceiling->thinker.function = T_MoveCeiling;
		ceiling->sector = sec;
		ceiling->crush = 0;
		ceiling->speed = arg[1] * (FRACUNIT / 8);
		switch (type)
		{
		case CLEV_CRUSHRAISEANDSTAY:
			ceiling->crush = arg[2];	// arg[2] = crushing value
			ceiling->topheight = sec->ceilingheight;
			ceiling->bottomheight = sec->floorheight + (8 * FRACUNIT);
			ceiling->direction = -1;
			break;
		case CLEV_CRUSHANDRAISE:
			ceiling->topheight = sec->ceilingheight;
		case CLEV_LOWERANDCRUSH:
			ceiling->crush = arg[2];	// arg[2] = crushing value
		case CLEV_LOWERTOFLOOR:
			ceiling->bottomheight = sec->floorheight;
			if(type != CLEV_LOWERTOFLOOR)
			{
				ceiling->bottomheight += 8 * FRACUNIT;
			}
			ceiling->direction = -1;
			break;
		case CLEV_RAISETOHIGHEST:
			ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
			ceiling->direction = 1;
			break;
		case CLEV_LOWERBYVALUE:
			ceiling->bottomheight = sec->ceilingheight - arg[2] * FRACUNIT;
			ceiling->direction = -1;
			break;
		case CLEV_RAISEBYVALUE:
			ceiling->topheight = sec->ceilingheight + arg[2] * FRACUNIT;
			ceiling->direction = 1;
			break;
		case CLEV_MOVETOVALUETIMES8:
			{
				int     destHeight = arg[2] * FRACUNIT * 8;

				if(arg[3])
				{
					destHeight = -destHeight;
				}
				if(sec->ceilingheight <= destHeight)
				{
					ceiling->direction = 1;
					ceiling->topheight = destHeight;
					if(sec->ceilingheight == destHeight)
					{
						rtn = 0;
					}
				}
				else if(sec->ceilingheight > destHeight)
				{
					ceiling->direction = -1;
					ceiling->bottomheight = destHeight;
				}
				break;
			}
		default:
			rtn = 0;
			break;
		}
		ceiling->tag = sec->tag;
		ceiling->type = type;
		P_AddActiveCeiling(ceiling);
		if(rtn)
		{
			SN_StartSequence((mobj_t *) &ceiling->sector->soundorg,
							 SEQ_PLATFORM + ceiling->sector->seqType);
		}
	}
	return rtn;
}
Beispiel #13
0
//
// EV_DoCeiling
// Move a ceiling up/down and all around!
//
dboolean EV_DoCeiling(line_t *line, ceiling_e type)
{
    int         secnum = -1;
    dboolean    rtn = false;
    sector_t    *sec;
    ceiling_t   *ceiling;


    // Reactivate in-stasis ceilings...for certain types.
    switch (type)
    {
        case fastCrushAndRaise:
        case silentCrushAndRaise:
        case crushAndRaise:
            rtn = P_ActivateInStasisCeiling(line);

        default:
            break;
    }

    while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0)
    {
        sec = &sectors[secnum];
        if (P_SectorActive(ceiling_special, sec))
            continue;

        // new door thinker
        rtn = true;
        ceiling = Z_Malloc(sizeof(*ceiling), PU_LEVSPEC, 0);
        memset(ceiling, 0, sizeof(*ceiling));
        P_AddThinker(&ceiling->thinker);
        sec->ceilingdata = ceiling;
        ceiling->thinker.function = T_MoveCeiling;
        ceiling->sector = sec;
        ceiling->crush = false;

        switch (type)
        {
            case fastCrushAndRaise:
                ceiling->crush = true;
                ceiling->topheight = sec->ceilingheight;
                ceiling->bottomheight = sec->floorheight + 8 * FRACUNIT;
                ceiling->direction = -1;
                ceiling->speed = CEILSPEED * 2;
                break;

            case silentCrushAndRaise:
            case crushAndRaise:
                ceiling->crush = true;
                ceiling->topheight = sec->ceilingheight;

            case lowerAndCrush:
            case lowerToFloor:
                ceiling->bottomheight = sec->floorheight;
                if (type != lowerToFloor && !(gamemission == doom2 && gamemap == 4 && canmodify))
                    ceiling->bottomheight += 8 * FRACUNIT;
                ceiling->direction = -1;
                ceiling->speed = CEILSPEED;
                break;

            case raiseToHighest:
                ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
                ceiling->direction = 1;
                ceiling->speed = CEILSPEED;
                break;

            case lowerToLowest:
                ceiling->bottomheight = P_FindLowestCeilingSurrounding(sec);
                ceiling->direction = -1;
                ceiling->speed = CEILSPEED;
                break;

            case lowerToMaxFloor:
                ceiling->bottomheight = P_FindHighestFloorSurrounding(sec);
                ceiling->direction = -1;
                ceiling->speed = CEILSPEED;
                break;
        }

        ceiling->tag = sec->tag;
        ceiling->type = type;
        P_AddActiveCeiling(ceiling);
    }
    return rtn;
}