Beispiel #1
0
void P_RecalculateAttached3DFloors(sector_t * sec)
{
	extsector_t::xfloor &x = sec->e->XFloor;

	for(unsigned int i=0; i<x.attached.Size(); i++)
	{
		P_Recalculate3DFloors(x.attached[i]);
	}
	P_Recalculate3DFloors(sec);
}
//==========================================================================
//
// Spawns 3D floors
//
//==========================================================================
void P_Spawn3DFloors (void)
{
	static int flagvals[] = {128+512, 2+512, 512};
	int i;
	line_t * line;

	for (i=0,line=lines;i<numlines;i++,line++)
	{
		switch(line->special)
		{
		case ExtraFloor_LightOnly:
			// Note: I am spawning both this and ZDoom's ExtraLight data
			// I don't want to mess with both at the same time during rendering
			// so inserting this into the 3D-floor table as well seemed to be
			// the best option.
			//
			// This does not yet handle case 0 properly!
			if (line->args[1] < 0 || line->args[1] > 2) line->args[1] = 0;
			P_Set3DFloor(line, 3, flagvals[line->args[1]], 0);
			break;

		case Sector_Set3DFloor:
			// The flag high-byte/line id is only needed in Hexen format.
			// UDMF can set both of these parameters without any restriction of the usable values.
			// In Doom format the translators can take full integers for the tag and the line ID always is the same as the tag.
			if (level.maptype == MAPTYPE_HEXEN)	
			{
				if (line->args[1]&8)
				{
					tagManager.AddLineID(i, line->args[4]);
				}
				else
				{
					line->args[0]+=256*line->args[4];
					line->args[4]=0;
				}
			}
			P_Set3DFloor(line, line->args[1]&~8, line->args[2], line->args[3]);
			break;

		default:
			continue;
		}
		line->special=0;
		line->args[0] = line->args[1] = line->args[2] = line->args[3] = line->args[4] = 0;
	}
	// kg3D - do it in software
	for (i = 0; i < numsectors; i++)
	{
		P_Recalculate3DFloors(&sectors[i]);
	}
}
Beispiel #3
0
//==========================================================================
//
// Spawns 3D floors
//
//==========================================================================
void P_Spawn3DFloors (void)
{
	static int flagvals[] = {512, 2+512, 512+1024};
	int i;
	line_t * line;

	for (i=0,line=lines;i<numlines;i++,line++)
	{
		switch(line->special)
		{
		case ExtraFloor_LightOnly:
			if (line->args[1] < 0 || line->args[1] > 2) line->args[1] = 0;
			P_Set3DFloor(line, 3, flagvals[line->args[1]], 0);
			break;

		case Sector_Set3DFloor:
			// The flag high-byte/line id is only needed in Hexen format.
			// UDMF can set both of these parameters without any restriction of the usable values.
			// In Doom format the translators can take full integers for the tag and the line ID always is the same as the tag.
			if (level.maptype == MAPTYPE_HEXEN)	
			{
				if (line->args[1]&8)
				{
					tagManager.AddLineID(i, line->args[4]);
				}
				else
				{
					line->args[0]+=256*line->args[4];
					line->args[4]=0;
				}
			}
			P_Set3DFloor(line, line->args[1]&~8, line->args[2], line->args[3]);
			break;

		default:
			continue;
		}
		line->special=0;
		line->args[0] = line->args[1] = line->args[2] = line->args[3] = line->args[4] = 0;
	}
	// kg3D - do it in software
	for (i = 0; i < numsectors; i++)
	{
		P_Recalculate3DFloors(&sectors[i]);
	}
}
Beispiel #4
0
void G_SerializeLevel(FSerializer &arc, bool hubload)
{
	int i = level.totaltime;

	if (arc.isWriting())
	{
		arc.Array("checksum", level.md5, 16);
	}
	else
	{
		// prevent bad things from happening by doing a check on the size of level arrays and the map's entire checksum.
		// The old code happily tried to load savegames with any mismatch here, often causing meaningless errors
		// deep down in the deserializer or just a crash if the few insufficient safeguards were not triggered.
		BYTE chk[16] = { 0 };
		arc.Array("checksum", chk, 16);
		if (arc.GetSize("linedefs") != (unsigned)numlines ||
			arc.GetSize("sidedefs") != (unsigned)numsides ||
			arc.GetSize("sectors") != (unsigned)numsectors ||
			arc.GetSize("polyobjs") != (unsigned)po_NumPolyobjs ||
			memcmp(chk, level.md5, 16))
		{
			I_Error("Savegame is from a different level");
		}
	}
	arc("saveversion", SaveVersion);

	Renderer->StartSerialize(arc);
	if (arc.isReading())
	{
		DThinker::DestroyAllThinkers();
		interpolator.ClearInterpolations();
		arc.ReadObjects(hubload);
	}

	arc("level.flags", level.flags)
		("level.flags2", level.flags2)
		("level.fadeto", level.fadeto)
		("level.found_secrets", level.found_secrets)
		("level.found_items", level.found_items)
		("level.killed_monsters", level.killed_monsters)
		("level.total_secrets", level.total_secrets)
		("level.total_items", level.total_items)
		("level.total_monsters", level.total_monsters)
		("level.gravity", level.gravity)
		("level.aircontrol", level.aircontrol)
		("level.teamdamage", level.teamdamage)
		("level.maptime", level.maptime)
		("level.totaltime", i)
		("level.skytexture1", level.skytexture1)
		("level.skytexture2", level.skytexture2);

	// Hub transitions must keep the current total time
	if (!hubload)
		level.totaltime = i;

	if (arc.isReading())
	{
		sky1texture = level.skytexture1;
		sky2texture = level.skytexture2;
		R_InitSkyMap();
		G_AirControlChanged();
	}



	// fixme: This needs to ensure it reads from the correct place. Should be one once there's enough of this code converted to JSON

	FBehavior::StaticSerializeModuleStates(arc);
	// The order here is important: First world state, then portal state, then thinkers, and last polyobjects.
	arc.Array("linedefs", lines, &loadlines[0], numlines);
	arc.Array("sidedefs", sides, &loadsides[0], numsides);
	arc.Array("sectors", sectors, &loadsectors[0], numsectors);
	arc("zones", Zones);
	arc("lineportals", linePortals);
	arc("sectorportals", sectorPortals);
	if (arc.isReading()) P_CollectLinkedPortals();

	DThinker::SerializeThinkers(arc, !hubload);
	arc.Array("polyobjs", polyobjs, po_NumPolyobjs);
	arc("subsectors", subsectors);
	StatusBar->SerializeMessages(arc);
	AM_SerializeMarkers(arc);
	FRemapTable::StaticSerializeTranslations(arc);
	FCanvasTextureInfo::Serialize(arc);
	P_SerializePlayers(arc, hubload);
	P_SerializeSounds(arc);

	if (arc.isReading())
	{
		for (int i = 0; i < numsectors; i++)
		{
			P_Recalculate3DFloors(&sectors[i]);
		}
		for (int i = 0; i < MAXPLAYERS; ++i)
		{
			if (playeringame[i] && players[i].mo != NULL)
			{
				players[i].mo->SetupWeaponSlots();
			}
		}
	}
	Renderer->EndSerialize(arc);

}
Beispiel #5
0
static void PrepareTransparentDoors(sector_t * sector)
{
    bool solidwall=false;
    int notextures=0;
    int nobtextures=0;
    int selfref=0;
    int i;
    sector_t * nextsec=NULL;

#ifdef _DEBUG
    if (sector-sectors==2)
    {
        int a = 0;
    }
#endif

    P_Recalculate3DFloors(sector);
    if (sector->subsectorcount==0) return;

    sector->transdoorheight=sector->GetPlaneTexZ(sector_t::floor);
    sector->transdoor= !(sector->e->XFloor.ffloors.Size() || sector->heightsec || sector->floorplane.isSlope());

    if (sector->transdoor)
    {
        for (i=0; i<sector->linecount; i++)
        {
            if (sector->lines[i]->frontsector==sector->lines[i]->backsector)
            {
                selfref++;
                continue;
            }

            sector_t * sec=getNextSector(sector->lines[i], sector);
            if (sec==NULL)
            {
                solidwall=true;
                continue;
            }
            else
            {
                nextsec=sec;

                int side = sector->lines[i]->sidedef[0]->sector == sec;

                if (sector->GetPlaneTexZ(sector_t::floor)!=sec->GetPlaneTexZ(sector_t::floor)+1. || sec->floorplane.isSlope())
                {
                    sector->transdoor=false;
                    return;
                }
                if (!sector->lines[i]->sidedef[1-side]->GetTexture(side_t::top).isValid()) notextures++;
                if (!sector->lines[i]->sidedef[1-side]->GetTexture(side_t::bottom).isValid()) nobtextures++;
            }
        }
        if (sector->GetTexture(sector_t::ceiling)==skyflatnum)
        {
            sector->transdoor=false;
            return;
        }

        if (selfref+nobtextures!=sector->linecount)
        {
            sector->transdoor=false;
        }

        if (selfref+notextures!=sector->linecount)
        {
            // This is a crude attempt to fix an incorrect transparent door effect I found in some
            // WolfenDoom maps but considering the amount of code required to handle it I left it in.
            // Do this only if the sector only contains one-sided walls or ones with no lower texture.
            if (solidwall)
            {
                if (solidwall+nobtextures+selfref==sector->linecount && nextsec)
                {
                    sector->heightsec=nextsec;
                    sector->heightsec->MoreFlags=0;
                }
                sector->transdoor=false;
            }
        }
    }
}
Beispiel #6
0
void G_SerializeLevel (FArchive &arc, bool hubLoad)
{
	int i = level.totaltime;
	
	Renderer->StartSerialize(arc);

	arc << level.flags
		<< level.flags2
		<< level.fadeto
		<< level.found_secrets
		<< level.found_items
		<< level.killed_monsters
		<< level.gravity
		<< level.aircontrol
		<< level.teamdamage
		<< level.maptime
		<< i;

	if (SaveVersion >= 3313)
	{
		arc << level.nextmusic;
	}

	// Hub transitions must keep the current total time
	if (!hubLoad)
		level.totaltime = i;

	if (SaveVersion >= 4507)
	{
		arc << level.skytexture1 << level.skytexture2;
	}
	else
	{
		level.skytexture1 = TexMan.GetTexture(arc.ReadName(), FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst);
		level.skytexture2 = TexMan.GetTexture(arc.ReadName(), FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst);
	}
	if (arc.IsLoading())
	{
		sky1texture = level.skytexture1;
		sky2texture = level.skytexture2;
		R_InitSkyMap();
	}

	G_AirControlChanged ();

	BYTE t;

	// Does this level have scrollers?
	if (arc.IsStoring ())
	{
		t = level.Scrolls ? 1 : 0;
		arc << t;
	}
	else
	{
		arc << t;
		if (level.Scrolls)
		{
			delete[] level.Scrolls;
			level.Scrolls = NULL;
		}
		if (t)
		{
			level.Scrolls = new FSectorScrollValues[numsectors];
			memset (level.Scrolls, 0, sizeof(level.Scrolls)*numsectors);
		}
	}

	FBehavior::StaticSerializeModuleStates (arc);
	if (arc.IsLoading()) interpolator.ClearInterpolations();
	P_SerializeThinkers (arc, hubLoad);
	P_SerializeWorld (arc);
	P_SerializePolyobjs (arc);
	P_SerializeSubsectors(arc);
	StatusBar->Serialize (arc);

	if (SaveVersion >= 4222)
	{ // This must be done *after* thinkers are serialized.
		arc << level.DefaultSkybox;
	}

	arc << level.total_monsters << level.total_items << level.total_secrets;

	// Does this level have custom translations?
	FRemapTable *trans;
	WORD w;
	if (arc.IsStoring ())
	{
		for (unsigned int i = 0; i < translationtables[TRANSLATION_LevelScripted].Size(); ++i)
		{
			trans = translationtables[TRANSLATION_LevelScripted][i];
			if (trans != NULL && !trans->IsIdentity())
			{
				w = WORD(i);
				arc << w;
				trans->Serialize(arc);
			}
		}
		w = 0xffff;
		arc << w;
	}
	else
	{
		while (arc << w, w != 0xffff)
		{
			trans = translationtables[TRANSLATION_LevelScripted].GetVal(w);
			if (trans == NULL)
			{
				trans = new FRemapTable;
				translationtables[TRANSLATION_LevelScripted].SetVal(w, trans);
			}
			trans->Serialize(arc);
		}
	}

	// This must be saved, too, of course!
	FCanvasTextureInfo::Serialize (arc);
	AM_SerializeMarkers(arc);

	P_SerializePlayers (arc, hubLoad);
	P_SerializeSounds (arc);
	if (arc.IsLoading())
	{
		for (i = 0; i < numsectors; i++)
		{
			P_Recalculate3DFloors(&sectors[i]);
		}
		for (i = 0; i < MAXPLAYERS; ++i)
		{
			if (playeringame[i] && players[i].mo != NULL)
			{
				players[i].mo->SetupWeaponSlots();
			}
		}
	}
	Renderer->EndSerialize(arc);
}
Beispiel #7
0
void G_SerializeLevel (FArchive &arc, bool hubLoad)
{
	int i = level.totaltime;
	
	Renderer->StartSerialize(arc);
	if (arc.IsLoading()) P_DestroyThinkers(hubLoad);

	arc << level.flags
		<< level.flags2
		<< level.fadeto
		<< level.found_secrets
		<< level.found_items
		<< level.killed_monsters
		<< level.gravity
		<< level.aircontrol
		<< level.teamdamage
		<< level.maptime
		<< i;

	// Hub transitions must keep the current total time
	if (!hubLoad)
		level.totaltime = i;

	arc << level.skytexture1 << level.skytexture2;
	if (arc.IsLoading())
	{
		sky1texture = level.skytexture1;
		sky2texture = level.skytexture2;
		R_InitSkyMap();
	}

	G_AirControlChanged ();

	BYTE t;

	// Does this level have scrollers?
	if (arc.IsStoring ())
	{
		t = level.Scrolls ? 1 : 0;
		arc << t;
	}
	else
	{
		arc << t;
		if (level.Scrolls)
		{
			delete[] level.Scrolls;
			level.Scrolls = NULL;
		}
		if (t)
		{
			level.Scrolls = new FSectorScrollValues[numsectors];
			memset (level.Scrolls, 0, sizeof(level.Scrolls)*numsectors);
		}
	}

	FBehavior::StaticSerializeModuleStates (arc);
	if (arc.IsLoading()) interpolator.ClearInterpolations();
	P_SerializeWorld(arc);
	P_SerializeThinkers (arc, hubLoad);
	P_SerializeWorldActors(arc);	// serializing actor pointers in the world data must be done after SerializeWorld has restored the entire sector state, otherwise LinkToWorld may fail.
	P_SerializePolyobjs (arc);
	P_SerializeSubsectors(arc);
	StatusBar->Serialize (arc);

	arc << level.total_monsters << level.total_items << level.total_secrets;

	// Does this level have custom translations?
	FRemapTable *trans;
	WORD w;
	if (arc.IsStoring ())
	{
		for (unsigned int i = 0; i < translationtables[TRANSLATION_LevelScripted].Size(); ++i)
		{
			trans = translationtables[TRANSLATION_LevelScripted][i];
			if (trans != NULL && !trans->IsIdentity())
			{
				w = WORD(i);
				arc << w;
				trans->Serialize(arc);
			}
		}
		w = 0xffff;
		arc << w;
	}
	else
	{
		while (arc << w, w != 0xffff)
		{
			trans = translationtables[TRANSLATION_LevelScripted].GetVal(w);
			if (trans == NULL)
			{
				trans = new FRemapTable;
				translationtables[TRANSLATION_LevelScripted].SetVal(w, trans);
			}
			trans->Serialize(arc);
		}
	}

	// This must be saved, too, of course!
	FCanvasTextureInfo::Serialize (arc);
	AM_SerializeMarkers(arc);

	P_SerializePlayers (arc, hubLoad);
	P_SerializeSounds (arc);
	if (arc.IsLoading())
	{
		for (i = 0; i < numsectors; i++)
		{
			P_Recalculate3DFloors(&sectors[i]);
		}
		for (i = 0; i < MAXPLAYERS; ++i)
		{
			if (playeringame[i] && players[i].mo != NULL)
			{
				players[i].mo->SetupWeaponSlots();
			}
		}
	}
	Renderer->EndSerialize(arc);
}