示例#1
0
//
// CL_ResetSectors
//
void CL_ResetSectors (void)
{
	for(size_t i = 0; i < real_plats.size(); i++)
	{
		plat_pred_t *pred = &real_plats[i];
		sector_t *sec = &sectors[pred->secnum];

		if(!sec->floordata)
		{
			if(real_plats.erase(real_plats.begin() + i) == real_plats.end())
				break;
			
			continue;
		}

		if(sec->floordata->IsKindOf(RUNTIME_CLASS(DPlat)))
		{
			DPlat *plat = (DPlat *)sec->floordata;
			sec->floorheight = pred->floorheight;
			plat->SetState(pred->state, pred->count);
		}
		else if(sec->floordata && sec->floordata->IsKindOf(RUNTIME_CLASS(DMovingFloor)))
		{
			sec->floorheight = pred->floorheight;
		}
	}
}
示例#2
0
void EV_StopPlat (int tag)
{
	DPlat *scan;
	TThinkerIterator<DPlat> iterator;

	while ( (scan = iterator.Next ()) )
	{
		if (scan->m_Status != DPlat::in_stasis && scan->m_Tag == tag)
			scan->Stop ();
	}
}
示例#3
0
void P_ActivateInStasis (int tag)
{
	DPlat *scan;
	TThinkerIterator<DPlat> iterator;

	while ( (scan = iterator.Next ()) )
	{
		if (scan->m_Tag == tag && scan->m_Status == DPlat::in_stasis)
			scan->Reactivate ();
	}
}
示例#4
0
void FLevelLocals::ActivateInStasisPlat (int tag)
{
	DPlat *scan;
	auto iterator = GetThinkerIterator<DPlat>();

	while ( (scan = iterator.Next ()) )
	{
		if (scan->m_Tag == tag && scan->m_Status == DPlat::in_stasis)
			scan->Reactivate ();
	}
}
示例#5
0
void FLevelLocals::EV_StopPlat (int tag, bool remove)
{
	DPlat *scan;
	auto iterator = GetThinkerIterator<DPlat>();

	scan = iterator.Next();
	while (scan != nullptr)
	{
		DPlat *next = iterator.Next();
		if (scan->m_Status != DPlat::in_stasis && scan->m_Tag == tag)
		{
			if (!remove) scan->Stop();
			else scan->Destroy();
		}
		scan = next;
	}
}
示例#6
0
//
// Do Platforms
//	[RH] Changed amount to height and added delay,
//		 lip, change, tag, and speed parameters.
//
BOOL EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height,
				int speed, int delay, int lip, int change)
{
	DPlat *plat;
	int secnum;
	sector_t *sec;
	int rtn = false;
	BOOL manual = false;

	// [RH] If tag is zero, use the sector on the back side
	//		of the activating line (if any).
	if (!tag)
	{
		if (!line || !(sec = line->backsector))
			return false;
		secnum = sec - sectors;
		manual = true;
		goto manual_plat;
	}

	//	Activate all <type> plats that are in_stasis
	switch (type)
	{
	case DPlat::platToggle:
		rtn = true;
	case DPlat::platPerpetualRaise:
		P_ActivateInStasis (tag);
		break;
	
	default:
		break;
	}
		
	secnum = -1;
	while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
	{
		sec = &sectors[secnum];

manual_plat:
		if (sec->floordata)
			continue;
		
		// Find lowest & highest floors around sector
		rtn = true;
		plat = new DPlat (sec);

		plat->m_Type = type;
		plat->m_Crush = false;
		plat->m_Tag = tag;
		plat->m_Speed = speed;
		plat->m_Wait = delay;

		//jff 1/26/98 Avoid raise plat bouncing a head off a ceiling and then
		//going down forever -- default lower to plat height when triggered
		plat->m_Low = sec->floorheight;

		if (change)
		{
			if (line)
				sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
			if (change == 1)
				sec->special = 0;	// Stop damage and other stuff, if any
		}

		switch (type)
		{
		case DPlat::platRaiseAndStay:
			plat->m_High = P_FindNextHighestFloor (sec, sec->floorheight);
			plat->m_Status = DPlat::midup;
			plat->PlayPlatSound();
			break;

		case DPlat::platUpByValue:
		case DPlat::platUpByValueStay:
			plat->m_High = sec->floorheight + height;
			plat->m_Status = DPlat::midup;
			plat->PlayPlatSound();
			break;
		
		case DPlat::platDownByValue:
			plat->m_Low = sec->floorheight - height;
			plat->m_Status = DPlat::middown;
			plat->PlayPlatSound();
			break;

		case DPlat::platDownWaitUpStay:
			plat->m_Low = P_FindLowestFloorSurrounding (sec) + lip*FRACUNIT;

			if (plat->m_Low > sec->floorheight)
				plat->m_Low = sec->floorheight;

			plat->m_High = sec->floorheight;
			plat->m_Status = DPlat::down;
			plat->PlayPlatSound();
			break;
		
		case DPlat::platUpWaitDownStay:
			plat->m_High = P_FindHighestFloorSurrounding (sec);

			if (plat->m_High < sec->floorheight)
				plat->m_High = sec->floorheight;

			plat->m_Status = DPlat::up;
			plat->PlayPlatSound();
			break;

		case DPlat::platPerpetualRaise:
			plat->m_Low = P_FindLowestFloorSurrounding (sec) + lip*FRACUNIT;

			if (plat->m_Low > sec->floorheight)
				plat->m_Low = sec->floorheight;

			plat->m_High = P_FindHighestFloorSurrounding (sec);

			if (plat->m_High < sec->floorheight)
				plat->m_High = sec->floorheight;

			plat->m_Status = P_Random () & 1 ? DPlat::down : DPlat::up;

			plat->PlayPlatSound();
			break;

		case DPlat::platToggle:	//jff 3/14/98 add new type to support instant toggle
			plat->m_Crush = false;	//jff 3/14/98 crush anything in the way

			// set up toggling between ceiling, floor inclusive
			plat->m_Low = sec->ceilingheight;
			plat->m_High = sec->floorheight;
			plat->m_Status = DPlat::down;
// 			SN_StartSequence (sec, "Silence");
			break;

		case DPlat::platDownToNearestFloor:
			plat->m_Low = P_FindNextLowestFloor (sec, sec->floorheight) + lip*FRACUNIT;
			plat->m_Status = DPlat::down;
			plat->m_High = sec->floorheight;
			plat->PlayPlatSound();
			break;

		case DPlat::platDownToLowestCeiling:
		    plat->m_Low = P_FindLowestCeilingSurrounding (sec);
			plat->m_High = sec->floorheight;

			if (plat->m_Low > sec->floorheight)
				plat->m_Low = sec->floorheight;

			plat->m_Status = DPlat::down;
			plat->PlayPlatSound();
			break;

		default:
			break;
		}
		if (manual)
			return rtn;
	}
	return rtn;
}
示例#7
0
bool FLevelLocals::EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, double height, double speed, int delay, int lip, int change)
{
	DPlat *plat;
	int secnum;
	sector_t *sec;
	bool rtn = false;
	bool manual = false;
	double newheight = 0;
	vertex_t *spot;

	if (tag != 0)
	{
		//	Activate all <type> plats that are in_stasis
		switch (type)
		{
		case DPlat::platToggle:
			rtn = true;
		case DPlat::platPerpetualRaise:
			ActivateInStasisPlat (tag);
			break;

		default:
			break;
		}
	}


	// [RH] If tag is zero, use the sector on the back side
	//		of the activating line (if any).
	auto itr = GetSectorTagIterator(tag, line);
	while ((secnum = itr.Next()) >= 0)
	{
		sec = &sectors[secnum];

		if (sec->PlaneMoving(sector_t::floor))
		{
			continue;
		}

		// Find lowest & highest floors around sector
		rtn = true;
		plat = CreateThinker<DPlat> (sec);

		plat->m_Type = type;
		plat->m_Crush = -1;
		plat->m_Tag = tag;
		plat->m_Speed = speed;
		plat->m_Wait = delay;

		//jff 1/26/98 Avoid raise plat bouncing a head off a ceiling and then
		//going down forever -- default lower to plat height when triggered
		plat->m_Low = sec->floorplane.fD();

		if (change)
		{
			if (line)
				sec->SetTexture(sector_t::floor, line->sidedef[0]->sector->GetTexture(sector_t::floor));
			if (change == 1) sec->ClearSpecial();
		}

		switch (type)
		{
		case DPlat::platRaiseAndStay:
		case DPlat::platRaiseAndStayLockout:
			newheight = FindNextHighestFloor (sec, &spot);
			plat->m_High = sec->floorplane.PointToDist (spot, newheight);
			plat->m_Low = sec->floorplane.fD();
			plat->m_Status = DPlat::up;
			plat->PlayPlatSound ("Floor");
			sec->ClearSpecial();
			break;

		case DPlat::platUpByValue:
		case DPlat::platUpByValueStay:
			newheight = sec->floorplane.ZatPoint (sec->centerspot) + height;
			plat->m_High = sec->floorplane.PointToDist (sec->centerspot, newheight);
			plat->m_Low = sec->floorplane.fD();
			plat->m_Status = DPlat::up;
			plat->PlayPlatSound ("Floor");
			break;
		
		case DPlat::platDownByValue:
			newheight = sec->floorplane.ZatPoint (sec->centerspot) - height;
			plat->m_Low = sec->floorplane.PointToDist (sec->centerspot, newheight);
			plat->m_High = sec->floorplane.fD();
			plat->m_Status = DPlat::down;
			plat->PlayPlatSound ("Floor");
			break;

		case DPlat::platDownWaitUpStay:
		case DPlat::platDownWaitUpStayStone:
			newheight = FindLowestFloorSurrounding (sec, &spot) + lip;
			plat->m_Low = sec->floorplane.PointToDist (spot, newheight);

			if (plat->m_Low < sec->floorplane.fD())
				plat->m_Low = sec->floorplane.fD();

			plat->m_High = sec->floorplane.fD();
			plat->m_Status = DPlat::down;
			plat->PlayPlatSound (type == DPlat::platDownWaitUpStay ? "Platform" : "Floor");
			break;
		
		case DPlat::platUpNearestWaitDownStay:
			newheight = FindNextHighestFloor (sec, &spot);
			// Intentional fall-through

		case DPlat::platUpWaitDownStay:
			if (type == DPlat::platUpWaitDownStay)
			{
				newheight = FindHighestFloorSurrounding (sec, &spot);
			}
			plat->m_High = sec->floorplane.PointToDist (spot, newheight);
			plat->m_Low = sec->floorplane.fD();

			if (plat->m_High > sec->floorplane.fD())
				plat->m_High = sec->floorplane.fD();

			plat->m_Status = DPlat::up;
			plat->PlayPlatSound ("Platform");
			break;

		case DPlat::platPerpetualRaise:
			newheight = FindLowestFloorSurrounding (sec, &spot) + lip;
			plat->m_Low =  sec->floorplane.PointToDist (spot, newheight);

			if (plat->m_Low < sec->floorplane.fD())
				plat->m_Low = sec->floorplane.fD();

			newheight = FindHighestFloorSurrounding (sec, &spot);
			plat->m_High =  sec->floorplane.PointToDist (spot, newheight);

			if (plat->m_High > sec->floorplane.fD())
				plat->m_High = sec->floorplane.fD();

			plat->m_Status = pr_doplat() & 1 ? DPlat::up : DPlat::down;

			plat->PlayPlatSound ("Platform");
			break;

		case DPlat::platToggle:	//jff 3/14/98 add new type to support instant toggle
			plat->m_Crush = 10;	//jff 3/14/98 crush anything in the way

			// set up toggling between ceiling, floor inclusive
			newheight = FindLowestCeilingPoint(sec, &spot);
			plat->m_Low = sec->floorplane.PointToDist (spot, newheight);
			plat->m_High = sec->floorplane.fD();
			plat->m_Status = DPlat::down;
			SN_StartSequence (sec, CHAN_FLOOR, "Silence", 0);
			break;

		case DPlat::platDownToNearestFloor:
			newheight = FindNextLowestFloor (sec, &spot) + lip;
			plat->m_Low = sec->floorplane.PointToDist (spot, newheight);
			plat->m_Status = DPlat::down;
			plat->m_High = sec->floorplane.fD();
			plat->PlayPlatSound ("Platform");
			break;

		case DPlat::platDownToLowestCeiling:
			newheight = FindLowestCeilingSurrounding (sec, &spot);
		    plat->m_Low = sec->floorplane.PointToDist (spot, newheight);
			plat->m_High = sec->floorplane.fD();

			if (plat->m_Low < sec->floorplane.fD())
				plat->m_Low = sec->floorplane.fD();

			plat->m_Status = DPlat::down;
			plat->PlayPlatSound ("Platform");
			break;

		default:
			break;
		}
	}
	return rtn;
}
示例#8
0
BOOL EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing,
                int tag, int speed, int delay, card_t lock)
{
    BOOL		rtn = false;
    int 		secnum;
    sector_t*	sec;
    DDoor *door;

    if (lock && thing && !P_CheckKeys (thing->player, lock, tag))
        return false;

    if (tag == 0)
    {   // [RH] manual door
        if (!line)
            return false;

        // if the wrong side of door is pushed, give oof sound
        if (line->sidenum[1]==-1)				// killough
        {
            UV_SoundAvoidPlayer (thing, CHAN_VOICE, "player/male/grunt1", ATTN_NORM);
            return false;
        }

        // get the sector on the second side of activating linedef
        sec = sides[line->sidenum[1]].sector;
        secnum = sec-sectors;

        // if door already has a thinker, use it
        if (sec->ceilingdata && sec->ceilingdata->IsKindOf (RUNTIME_CLASS(DDoor)))
        {
            door = static_cast<DDoor *>(sec->ceilingdata);
            door->m_Line = line;

            // ONLY FOR "RAISE" DOORS, NOT "OPEN"s
            if (door->m_Type == DDoor::doorRaise && type == DDoor::doorRaise)
            {
                if (door->m_Direction == -1)
                {
                    door->m_Direction = 1;	// go back up
                }
                else if (GET_SPAC(line->flags) != SPAC_PUSH)
                    // [RH] activate push doors don't go back down when you
                    //		run into them (otherwise opening them would be
                    //		a real pain).
                {
                    if (thing && !thing->player)
                        return false;	// JDC: bad guys never close doors

                    // From Chocolate Doom:
                    // When is a door not a door?
                    // In Vanilla, door->direction is set, even though
                    // "specialdata" might not actually point at a door.

                    else if (sec->floordata && sec->floordata->IsKindOf (RUNTIME_CLASS(DPlat)))
                    {
                        // Erm, this is a plat, not a door.
                        // This notably causes a problem in ep1-0500.lmp where
                        // a plat and a door are cross-referenced; the door
                        // doesn't open on 64-bit.
                        // The direction field in vldoor_t corresponds to the wait
                        // field in plat_t.  Let's set that to -1 instead.

                        DPlat *plat = static_cast<DPlat *>(sec->floordata);
                        byte state;
                        int count;

                        plat->GetState(state, count);

                        if (count >= 16)    // ep1-0500 always returns a count of 16.
                            return false;   // We may be able to always return false?
                    }
                    else
                    {
                        door->m_Direction = -1;	// try going back down anyway?
                    }
                }
                return true;
            }
        }
        else
        {
            door = new DDoor(sec, line, type, speed, delay);
        }
        if (door)
        {
            rtn = true;
        }
    }
    else
    {   // [RH] Remote door

        secnum = -1;
        while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0)
        {
            sec = &sectors[secnum];
            // if the ceiling already moving, don't start the door action
            if (sec->ceilingdata)
                continue;

            if (new DDoor (sec, line, type, speed, delay))
                rtn = true;
        }

    }
    return rtn;
}