void WI_drawShowNextLoc () { int i; // draw animated background WI_drawAnimatedBack (); if (gamemode != commercial) { if (!(gameinfo.gametype & (GAME_Doom|GAME_Heretic)) || epsd > 2) { WI_drawEL(); return; } // draw a splat on taken cities. for (i = 0; i < NUMMAPS; i++) { if (FindLevelInfo (names[epsd][i])->flags & LEVEL_VISITED) WI_drawOnLnode (i, &splat, epsd); } // draw flashing ptr if (snl_pointeron) WI_drawOnLnode (WI_MapToIndex (wbs->next, wbs->next_ep), yah, wbs->next_ep); } // draws which level you are entering.. WI_drawEL(); }
void P_ReadACSDefereds (PNGHandle *png) { BYTE namelen; char mapname[256]; size_t chunklen; P_RemoveDefereds (); if ((chunklen = M_FindPNGChunk (png, ACSD_ID)) != 0) { FPNGChunkArchive arc (png->File->GetFile(), ACSD_ID, chunklen); arc << namelen; while (namelen) { arc.Read (mapname, namelen); mapname[namelen] = 0; level_info_t *i = FindLevelInfo (mapname); if (i == NULL) { I_Error ("Unknown map '%s' in savegame", mapname); } arc << i->defered; arc << namelen; } } png->File->ResetFilePtr(); }
void WI_drawShowNextLoc (void) { int i; // draw animated background WI_drawAnimatedBack (); if (gamemode != commercial && gamemode != commercial_bfg ) { if (wbs->epsd > 2) { WI_drawEL(); return; } // draw a splat on taken cities. for (i=0; i < NUMMAPS; i++) { if (FindLevelInfo (names[wbs->epsd][i])->flags & LEVEL_VISITED) WI_drawOnLnode(i, &splat, 1); } // draw flashing ptr if (snl_pointeron) WI_drawOnLnode(WI_MapToIndex (wbs->next), yah, 2); } // draws which level you are entering.. WI_drawEL(); }
void G_ReadVisited(FSerializer &arc) { if (arc.BeginArray("visited")) { for (int s = arc.ArraySize(); s > 0; s--) { FString str; arc(nullptr, str); auto i = FindLevelInfo(str); if (i != nullptr) i->flags |= LEVEL_VISITED; } arc.EndArray(); } arc.Array("randomclasses", SinglePlayerClass, MAXPLAYERS); if (arc.BeginObject("playerclasses")) { for (int i = 0; i < MAXPLAYERS; ++i) { FString key; key.Format("%d", i); arc(key, players[i].cls); } arc.EndObject(); } }
void P_ReadACSDefereds (PNGHandle *png) { BYTE namelen; char mapname[256]; FString MapName; size_t chunklen; P_RemoveDefereds (); if ((chunklen = M_FindPNGChunk (png, ACSD_ID)) != 0) { FPNGChunkArchive arc (png->File->GetFile(), ACSD_ID, chunklen); if (SaveVersion < 4508) { arc << namelen; while (namelen != 0) { arc.Read(mapname, namelen); mapname[namelen] = 0; level_info_t *i = FindLevelInfo(mapname); if (i == NULL) { I_Error("Unknown map '%s' in savegame", mapname); } arc << i->defered; arc << namelen; } } else { while (arc << MapName, MapName.Len() > 0) { level_info_t *i = FindLevelInfo(MapName); if (i == NULL) { I_Error("Unknown map '%s' in savegame", MapName.GetChars()); } arc << i->defered; } } } png->File->ResetFilePtr(); }
void P_ReadACSDefereds (FSerializer &arc) { FString MapName; P_RemoveDefereds (); if (arc.BeginObject("deferred")) { const char *key; while ((key = arc.GetKey())) { level_info_t *i = FindLevelInfo(key); if (i == NULL) { I_Error("Unknown map '%s' in savegame", key); } arc(nullptr, i->deferred); } arc.EndObject(); } }
void P_ReadACSDefereds (PNGHandle *png) { FString MapName; size_t chunklen; P_RemoveDefereds (); if ((chunklen = M_FindPNGChunk (png, ACSD_ID)) != 0) { FPNGChunkArchive arc (png->File->GetFile(), ACSD_ID, chunklen); while (arc << MapName, MapName.Len() > 0) { level_info_t *i = FindLevelInfo(MapName); if (i == NULL) { I_Error("Unknown map '%s' in savegame", MapName.GetChars()); } arc << i->defered; } } png->File->ResetFilePtr(); }
void WI_DrawDoomBack () { char name[9]; if ((gamemode == commercial) || (gamemode == retail && epsd >= 3)) strcpy (name, "INTERPIC"); else sprintf (name, "WIMAP%d", epsd); // background background = TexMan (name); if (FindLevelInfo ("E2M9")->flags & LEVEL_VISITED && epsd == 1) { // [RH] Add the Fortress of Mystery if it has been visited DrawFoM = true; // anims[1][7].data = 800; // Don't animate it again if the user uses changemap E2M9 } else { DrawFoM = false; anims[1][7].data = 8; } }
level_info_t *level_info_t::CheckLevelRedirect () { if (RedirectType != NAME_None) { const PClass *type = PClass::FindClass(RedirectType); if (type != NULL) { for (int i = 0; i < MAXPLAYERS; ++i) { if (playeringame[i] && players[i].mo->FindInventory (type)) { // check for actual presence of the map. if (P_CheckMapData(RedirectMap)) { return FindLevelInfo(RedirectMap); } break; } } } } return NULL; }
void G_ReadSnapshots(FResourceFile *resf) { FString MapName; level_info_t *i; G_ClearSnapshots(); for (unsigned j = 0; j < resf->LumpCount(); j++) { FResourceLump * resl = resf->GetLump(j); if (resl != nullptr) { auto ptr = strstr(resl->FullName, ".map.json"); if (ptr != nullptr) { ptrdiff_t maplen = ptr - resl->FullName.GetChars(); FString mapname(resl->FullName.GetChars(), (size_t)maplen); i = FindLevelInfo(mapname); if (i != nullptr) { i->Snapshot = resl->GetRawData(); } } else { auto ptr = strstr(resl->FullName, ".mapd.json"); if (ptr != nullptr) { ptrdiff_t maplen = ptr - resl->FullName.GetChars(); FString mapname(resl->FullName.GetChars(), (size_t)maplen); TheDefaultLevelInfo.Snapshot = resl->GetRawData(); } } } } }
void STAT_ChangeLevel(const char *newl) { // record the current level's stats. StoreLevelStats(); level_info_t *thisinfo = level.info; level_info_t *nextinfo = NULL; if (strncmp(newl, "enDSeQ", 6)) { level_info_t *l = FindLevelInfo (newl); nextinfo = l->CheckLevelRedirect (); if (nextinfo == NULL) nextinfo = l; } if (savestatistics == 1) { if ((nextinfo == NULL || (nextinfo->flags2 & LEVEL2_ENDGAME)) && StartEpisode != NULL) { // we reached the end of this episode int wad = 0; MapData * map = P_OpenMapData(StartEpisode->mEpisodeMap, false); if (map != NULL) { wad = Wads.GetLumpFile(map->lumpnum); delete map; } const char * name = Wads.GetWadName(wad); FString section = ExtractFileBase(name) + "." + StartEpisode->mEpisodeMap; section.ToUpper(); const char *ep_name = StartEpisode->mEpisodeName; if (*ep_name == '$') ep_name = GStrings[ep_name+1]; FStatistics *sl = GetStatisticsList(EpisodeStatistics, section, ep_name); int statvals[4] = {0,0,0,0}; FString infostring; int validlevels = LevelData.Size(); for(unsigned i = 0; i < LevelData.Size(); i++) { statvals[0] += LevelData[i].killcount; statvals[1] += LevelData[i].totalkills; statvals[2] += LevelData[i].secretcount; statvals[3] += LevelData[i].totalsecrets; } infostring.Format("%4d/%4d, %3d/%3d, %2d", statvals[0], statvals[1], statvals[2], statvals[3], validlevels); FSessionStatistics *es = StatisticsEntry(sl, infostring, AdjustTics(level.totaltime)); for(unsigned i = 0; i < LevelData.Size(); i++) { FString lsection = LevelData[i].Levelname; lsection.ToUpper(); infostring.Format("%4d/%4d, %3d/%3d", LevelData[i].killcount, LevelData[i].totalkills, LevelData[i].secretcount, LevelData[i].totalsecrets); LevelStatEntry(es, lsection, infostring, LevelData[i].leveltime); } SaveStatistics(statfile, EpisodeStatistics); } } else if (savestatistics == 2) // todo: handle single level statistics. { } }
void G_ReadSnapshots (PNGHandle *png) { DWORD chunkLen; BYTE namelen; char mapname[256]; level_info_t *i; G_ClearSnapshots (); chunkLen = (DWORD)M_FindPNGChunk (png, SNAP_ID); while (chunkLen != 0) { FPNGChunkArchive arc (png->File->GetFile(), SNAP_ID, chunkLen); DWORD snapver; arc << snapver; arc << namelen; arc.Read (mapname, namelen); mapname[namelen] = 0; i = FindLevelInfo (mapname); i->snapshotVer = snapver; i->snapshot = new FCompressedMemFile; i->snapshot->Serialize (arc); chunkLen = (DWORD)M_NextPNGChunk (png, SNAP_ID); } chunkLen = (DWORD)M_FindPNGChunk (png, DSNP_ID); if (chunkLen != 0) { FPNGChunkArchive arc (png->File->GetFile(), DSNP_ID, chunkLen); DWORD snapver; arc << snapver; arc << namelen; arc.Read (mapname, namelen); TheDefaultLevelInfo.snapshotVer = snapver; TheDefaultLevelInfo.snapshot = new FCompressedMemFile; TheDefaultLevelInfo.snapshot->Serialize (arc); } chunkLen = (DWORD)M_FindPNGChunk (png, VIST_ID); if (chunkLen != 0) { FPNGChunkArchive arc (png->File->GetFile(), VIST_ID, chunkLen); arc << namelen; while (namelen != 0) { arc.Read (mapname, namelen); mapname[namelen] = 0; i = FindLevelInfo (mapname); i->flags |= LEVEL_VISITED; arc << namelen; } } chunkLen = (DWORD)M_FindPNGChunk (png, RCLS_ID); if (chunkLen != 0) { FPNGChunkArchive arc (png->File->GetFile(), PCLS_ID, chunkLen); SBYTE cnum; for (DWORD j = 0; j < chunkLen; ++j) { arc << cnum; SinglePlayerClass[j] = cnum; } } chunkLen = (DWORD)M_FindPNGChunk (png, PCLS_ID); if (chunkLen != 0) { FPNGChunkArchive arc (png->File->GetFile(), RCLS_ID, chunkLen); BYTE pnum; arc << pnum; while (pnum != 255) { arc.UserReadClass (players[pnum].cls); arc << pnum; } } png->File->ResetFilePtr(); }
void WI_loadData (void) { int i, j; char name[9]; anim_t *a; patch_t *bg; if ((gameinfo.flags & GI_MAPxx) || ((gameinfo.flags & GI_MENUHACK_RETAIL) && wbs->epsd >= 3)) strcpy (name, "INTERPIC"); else sprintf (name, "WIMAP%d", wbs->epsd); // background bg = W_CachePatch (name); background = I_AllocateScreen (bg->width(), bg->height(), 8); background->Lock (); background->DrawPatch (bg, 0, 0); background->Unlock (); for (i = 0; i < 2; i++) { char *lname = (i == 0 ? wbs->lname0 : wbs->lname1); if (lname) j = W_CheckNumForName (lname); else j = -1; if (j >= 0) { lnames[i] = W_CachePatch (j, PU_STATIC); } else { lnames[i] = NULL; lnametexts[i] = FindLevelInfo (i == 0 ? wbs->current : wbs->next)->level_name; lnamewidths[i] = WI_CalcWidth (lnametexts[i]); } } if (gamemode != commercial && gamemode != commercial_bfg ) { // you are here yah[0] = W_CachePatch ("WIURH0", PU_STATIC); // you are here (alt.) yah[1] = W_CachePatch ("WIURH1", PU_STATIC); // splat splat = W_CachePatch ("WISPLAT", PU_STATIC); if (wbs->epsd < 3) { for (j=0; j<NUMANIMS[wbs->epsd]; j++) { a = &anims[wbs->epsd][j]; for (i=0; i<a->nanims; i++) { // MONDO HACK! if (wbs->epsd != 1 || j != 8) { // animations sprintf (name, "WIA%d%.2d%.2d", wbs->epsd, j, i); a->p[i] = W_CachePatch (name, PU_STATIC); } else { // HACK ALERT! a->p[i] = anims[1][4].p[i]; } } } } } for (i=0; i<10; i++) { // numbers 0-9 sprintf(name, "WINUM%d", i); num[i] = W_CachePatch (name, PU_STATIC); } wiminus = W_CachePatch ("WIMINUS", PU_STATIC); // percent sign percent = W_CachePatch ("WIPCNT", PU_STATIC); // ":" colon = W_CachePatch ("WICOLON", PU_STATIC); // "finished" finished = W_CachePatch ("WIF", PU_STATIC); // (Removed) Dan - Causes GUI Issues |FIX-ME| // "entering" entering = W_CachePatch ("WIENTER", PU_STATIC); // "kills" kills = W_CachePatch ("WIOSTK", PU_STATIC); // "items" items = W_CachePatch ("WIOSTI", PU_STATIC); // "scrt" scrt = W_CachePatch ("WIOSTS", PU_STATIC); // "secret" secret = W_CachePatch ("WISCRT2", PU_STATIC); // "frgs" frags = (patch_t *)W_CachePatch ("WIFRGS", PU_STATIC); // "time" timepatch = W_CachePatch ("WITIME", PU_STATIC); // "sucks" sucks =W_CachePatch ("WISUCKS", PU_STATIC); // "par" par = W_CachePatch ("WIPAR", PU_STATIC); // "total" total = (patch_t *)W_CachePatch ("WIMSTT", PU_STATIC); // your face star = (patch_t *)W_CachePatch ("STFST01", PU_STATIC); // dead face bstar = (patch_t *)W_CachePatch("STFDEAD0", PU_STATIC); p = W_CachePatch ("STPBANY", PU_STATIC); // [Nes] Classic vanilla lifebars. for (i = 0; i < 4; i++) { sprintf(name, "STPB%d", i); faceclassic[i] = W_CachePatch(name, PU_STATIC); } }
void WI_loadData () { int i, j; char name[9]; in_anim_t *a; if (gameinfo.gametype != GAME_Doom) { for (i = 0; i < 2; i++) { lnames[i] = NULL; lnametexts[i] = G_MaybeLookupLevelName (FindLevelInfo (i == 0 ? wbs->current : wbs->next)); lnamewidths[i] = WI_CalcWidth (lnametexts[i]); } if (gameinfo.gametype == GAME_Hexen) { background = TexMan["INTERPIC"]; return; } } if (gameinfo.gametype == GAME_Doom && gamemode != commercial && epsd < 3) { for (j = 0; j < NUMANIMS[epsd]; j++) { a = &anims[epsd][j]; for (i = 0; i < a->nanims; i++) { // MONDO HACK! if (epsd != 1 || j != 8) { // animations sprintf (name, "WIA%d%.2d%.2d", epsd, j, i); a->p[i] = TexMan[name]; } else { // HACK ALERT! a->p[i] = anims[1][4].p[i]; } } } } if (gameinfo.gametype == GAME_Doom) { WI_DrawDoomBack (); for (i = 0; i < 2; i++) { char *lname = (i == 0 ? wbs->lname0 : wbs->lname1); j = lname && lname[0] ? TexMan.CheckForTexture (lname, FTexture::TEX_MiscPatch) : -1; if (j > 0) { lnames[i] = TexMan[j]; } else { lnames[i] = NULL; if (i == 1 && strncmp (wbs->next, "enDSeQ", 6) == 0) { lnametexts[i] = NULL; lnamewidths[i] = 0; } else { lnametexts[i] = G_MaybeLookupLevelName (FindLevelInfo (i == 0 ? wbs->current : wbs->next)); lnamewidths[i] = WI_CalcWidth (lnametexts[i]); } } } } else { background = NULL; } if (gameinfo.gametype == GAME_Doom) { if (gamemode != commercial) { yah[0] = TexMan["WIURH0"]; // you are here yah[1] = TexMan["WIURH1"]; // you are here (alt.] splat = TexMan["WISPLAT"]; // splat } wiminus = TexMan["WIMINUS"]; // minus sign percent = TexMan["WIPCNT"]; // percent sign finished = TexMan["WIF"]; // "finished" entering = TexMan["WIENTER"]; // "entering" kills = TexMan["WIOSTK"]; // "kills" secret = TexMan["WIOSTS"]; // "scrt" sp_secret = TexMan["WISCRT2"]; // "secret" items = TexMan["WIOSTI"]; // "items" frags = TexMan["WIFRGS"]; // "frgs" colon = TexMan["WICOLON"]; // ":" timepic = TexMan["WITIME"]; // "time" sucks = TexMan["WISUCKS"]; // "sucks" par = TexMan["WIPAR"]; // "par" killers = TexMan["WIKILRS"]; // "killers" (vertical] victims = TexMan["WIVCTMS"]; // "victims" (horiz] total = TexMan["WIMSTT"]; // "total" star = TexMan["STFST01"]; // your face bstar = TexMan["STFDEAD0"]; // dead face p = TexMan["STPBANY"]; for (i = 0; i < 10; i++) { // numbers 0-9 sprintf (name, "WINUM%d", i); num[i] = TexMan[name]; } } else { yah[0] = yah[1] = TexMan["IN_YAH"]; splat = TexMan["IN_X"]; wiminus = TexMan["FONTB13"]; percent = TexMan["FONTB05"]; colon = TexMan["FONTB26"]; slash = TexMan["FONTB15"]; star = TexMan["FACEA0"]; bstar = TexMan["FACEB0"]; for (i = 0; i < 10; i++) { sprintf (name, "FONTB%d", 16 + i); num[i] = TexMan[name]; } } }
// This will get called if after an UMAPINFO lump a regular (Z)MAPINFO is found or when MAPINFO parsing is complete. void CommitUMapinfo(level_info_t *defaultinfo) { for (auto &map : Maps) { auto levelinfo = FindLevelInfo(map.MapName); if (levelinfo == nullptr) { // Map did not exist yet. auto levelindex = wadlevelinfos.Reserve(1); levelinfo = &wadlevelinfos[levelindex]; *levelinfo = *defaultinfo; } if (map.MapName.IsNotEmpty()) levelinfo->MapName = map.MapName; if (map.LevelName.IsNotEmpty()) { levelinfo->LevelName = map.LevelName; levelinfo->PName = ""; // clear the map name patch to force the string version to be shown - unless explicitly overridden right next. } if (map.levelpic[0]) levelinfo->PName = map.levelpic; if (map.nextmap[0]) levelinfo->NextMap = map.nextmap; else if (map.endpic[0]) { FName name = NAME_None; if (!stricmp(map.endpic, "$CAST")) { name = "INTER_CAST"; } else if (!stricmp(map.endpic, "$BUNNY")) { name = "INTER_BUNNY"; } else { name = MakeEndPic(map.endpic); } if (name != NAME_None) { levelinfo->NextMap.Format("enDSeQ%04x", int(name)); } } if (map.nextsecret[0]) levelinfo->NextSecretMap = map.nextsecret; if (map.music[0]) { levelinfo->Music = map.music; levelinfo->musicorder = 0; } if (map.skytexture[0]) { levelinfo->SkyPic1 = map.skytexture; levelinfo->skyspeed1 = 0; levelinfo->SkyPic2 = ""; levelinfo->skyspeed2 = 0; } if (map.partime > 0) levelinfo->partime = map.partime; if (map.enterpic[0]) levelinfo->EnterPic = map.enterpic; if (map.exitpic[0]) levelinfo->ExitPic = map.exitpic; if (map.intermusic[0]) { levelinfo->InterMusic = map.intermusic; levelinfo->intermusicorder = 0; } if (map.BossActions.Size() > 0) { // Setting a boss action will deactivate the flag based monster actions. levelinfo->specialactions = std::move(map.BossActions); levelinfo->flags &= ~(LEVEL_BRUISERSPECIAL | LEVEL_CYBORGSPECIAL | LEVEL_SPIDERSPECIAL | LEVEL_MAP07SPECIAL | LEVEL_MINOTAURSPECIAL | LEVEL_HEADSPECIAL | LEVEL_SORCERER2SPECIAL | LEVEL_SPECACTIONSMASK | LEVEL_SPECKILLMONSTERS); } const int exflags = FExitText::DEF_TEXT | FExitText::DEF_BACKDROP | FExitText::DEF_MUSIC; if (map.InterText.IsNotEmpty()) { if (map.InterText.Compare("-") != 0) levelinfo->ExitMapTexts[NAME_Normal] = { exflags, 0, map.InterText, map.interbackdrop, map.intermusic[0]? map.intermusic : gameinfo.intermissionMusic }; else levelinfo->ExitMapTexts[NAME_Normal] = { 0, 0 }; } if (map.InterTextSecret.IsNotEmpty()) { if (map.InterTextSecret.Compare("-") != 0) levelinfo->ExitMapTexts[NAME_Secret] = { exflags, 0, map.InterTextSecret, map.interbackdrop, map.intermusic[0] ? map.intermusic : gameinfo.intermissionMusic }; else levelinfo->ExitMapTexts[NAME_Secret] = { 0, 0 }; } if (map.nointermission) levelinfo->flags |= LEVEL_NOINTERMISSION; } // All done. If we get here again, start fresh. Maps.Clear(); Maps.ShrinkToFit(); }
void G_WorldDone (void) { cluster_info_t *nextcluster; cluster_info_t *thiscluster; gameaction = ga_worlddone; if (level.flags & LEVEL_CHANGEMAPCHEAT) return; thiscluster = FindClusterInfo (level.cluster); if (strncmp (nextlevel, "enDSeQ", 6) == 0) { FName endsequence = ENamedName(strtol(nextlevel.GetChars()+6, NULL, 16)); // Strife needs a special case here to choose between good and sad ending. Bad is handled elsewherw. if (endsequence == NAME_Inter_Strife) { if (players[0].mo->FindInventory (QuestItemClasses[24]) || players[0].mo->FindInventory (QuestItemClasses[27])) { endsequence = NAME_Inter_Strife_Good; } else { endsequence = NAME_Inter_Strife_Sad; } } F_StartFinale (thiscluster->MessageMusic, thiscluster->musicorder, thiscluster->cdtrack, thiscluster->cdid, thiscluster->FinaleFlat, thiscluster->ExitText, thiscluster->flags & CLUSTER_EXITTEXTINLUMP, thiscluster->flags & CLUSTER_FINALEPIC, thiscluster->flags & CLUSTER_LOOKUPEXITTEXT, true, endsequence); } else { nextcluster = FindClusterInfo (FindLevelInfo (nextlevel)->cluster); if (nextcluster->cluster != level.cluster && !deathmatch) { // Only start the finale if the next level's cluster is different // than the current one and we're not in deathmatch. if (nextcluster->EnterText.IsNotEmpty()) { F_StartFinale (nextcluster->MessageMusic, nextcluster->musicorder, nextcluster->cdtrack, nextcluster->cdid, nextcluster->FinaleFlat, nextcluster->EnterText, nextcluster->flags & CLUSTER_ENTERTEXTINLUMP, nextcluster->flags & CLUSTER_FINALEPIC, nextcluster->flags & CLUSTER_LOOKUPENTERTEXT, false); } else if (thiscluster->ExitText.IsNotEmpty()) { F_StartFinale (thiscluster->MessageMusic, thiscluster->musicorder, thiscluster->cdtrack, nextcluster->cdid, thiscluster->FinaleFlat, thiscluster->ExitText, thiscluster->flags & CLUSTER_EXITTEXTINLUMP, thiscluster->flags & CLUSTER_FINALEPIC, thiscluster->flags & CLUSTER_LOOKUPEXITTEXT, false); } } } }
void G_DoCompleted (void) { int i; gameaction = ga_nothing; if (gamestate == GS_TITLELEVEL) { level.MapName = nextlevel; G_DoLoadLevel (startpos, false); startpos = 0; viewactive = true; return; } // [RH] Mark this level as having been visited if (!(level.flags & LEVEL_CHANGEMAPCHEAT)) FindLevelInfo (level.MapName)->flags |= LEVEL_VISITED; if (automapactive) AM_Stop (); wminfo.finished_ep = level.cluster - 1; wminfo.LName0 = TexMan[TexMan.CheckForTexture(level.info->PName, FTexture::TEX_MiscPatch)]; wminfo.current = level.MapName; if (deathmatch && (dmflags & DF_SAME_LEVEL) && !(level.flags & LEVEL_CHANGEMAPCHEAT)) { wminfo.next = level.MapName; wminfo.LName1 = wminfo.LName0; } else { level_info_t *nextinfo = FindLevelInfo (nextlevel, false); if (nextinfo == NULL || strncmp (nextlevel, "enDSeQ", 6) == 0) { wminfo.next = nextlevel; wminfo.LName1 = NULL; } else { wminfo.next = nextinfo->MapName; wminfo.LName1 = TexMan[TexMan.CheckForTexture(nextinfo->PName, FTexture::TEX_MiscPatch)]; } } CheckWarpTransMap (wminfo.next, true); nextlevel = wminfo.next; wminfo.next_ep = FindLevelInfo (wminfo.next)->cluster - 1; wminfo.maxkills = level.total_monsters; wminfo.maxitems = level.total_items; wminfo.maxsecret = level.total_secrets; wminfo.maxfrags = 0; wminfo.partime = TICRATE * level.partime; wminfo.sucktime = level.sucktime; wminfo.pnum = consoleplayer; wminfo.totaltime = level.totaltime; for (i=0 ; i<MAXPLAYERS ; i++) { wminfo.plyr[i].in = playeringame[i]; wminfo.plyr[i].skills = players[i].killcount; wminfo.plyr[i].sitems = players[i].itemcount; wminfo.plyr[i].ssecret = players[i].secretcount; wminfo.plyr[i].stime = level.time; memcpy (wminfo.plyr[i].frags, players[i].frags , sizeof(wminfo.plyr[i].frags)); wminfo.plyr[i].fragcount = players[i].fragcount; } // [RH] If we're in a hub and staying within that hub, take a snapshot // of the level. If we're traveling to a new hub, take stuff from // the player and clear the world vars. If this is just an // ordinary cluster (not a hub), take stuff from the player, but // leave the world vars alone. cluster_info_t *thiscluster = FindClusterInfo (level.cluster); cluster_info_t *nextcluster = FindClusterInfo (wminfo.next_ep+1); // next_ep is cluster-1 EFinishLevelType mode; if (thiscluster != nextcluster || deathmatch || !(thiscluster->flags & CLUSTER_HUB)) { if (nextcluster->flags & CLUSTER_HUB) { mode = FINISH_NextHub; } else { mode = FINISH_NoHub; } } else { mode = FINISH_SameHub; } // Intermission stats for entire hubs G_LeavingHub(mode, thiscluster, &wminfo); for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i]) { // take away appropriate inventory G_PlayerFinishLevel (i, mode, changeflags); } } if (mode == FINISH_SameHub) { // Remember the level's state for re-entry. if (!(level.flags2 & LEVEL2_FORGETSTATE)) { G_SnapshotLevel (); // Do not free any global strings this level might reference // while it's not loaded. FBehavior::StaticLockLevelVarStrings(); } else { // Make sure we don't have a snapshot lying around from before. level.info->ClearSnapshot(); } } else { // Forget the states of all existing levels. G_ClearSnapshots (); if (mode == FINISH_NextHub) { // Reset world variables for the new hub. P_ClearACSVars(false); } level.time = 0; level.maptime = 0; } if (!deathmatch && ((level.flags & LEVEL_NOINTERMISSION) || ((nextcluster == thiscluster) && (thiscluster->flags & CLUSTER_HUB)))) { G_WorldDone (); return; } gamestate = GS_INTERMISSION; viewactive = false; automapactive = false; // [RH] If you ever get a statistics driver operational, adapt this. // if (statcopy) // memcpy (statcopy, &wminfo, sizeof(wminfo)); WI_Start (&wminfo); }
void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill) { level_info_t *nextinfo = NULL; if (unloading) { Printf (TEXTCOLOR_RED "Unloading scripts cannot exit the level again.\n"); return; } if (levelname == NULL || *levelname == 0) { // end the game levelname = NULL; if (!level.NextMap.Compare("enDSeQ",6)) { nextlevel = level.NextMap; // If there is already an end sequence please leave it alone! } else { nextlevel.Format("enDSeQ%04x", int(gameinfo.DefaultEndSequence)); } } else if (strncmp(levelname, "enDSeQ", 6) != 0) { nextinfo = FindLevelInfo (levelname, false); if (nextinfo != NULL) { level_info_t *nextredir = nextinfo->CheckLevelRedirect(); if (nextredir != NULL) { nextinfo = nextredir; } } nextlevel = nextinfo->MapName; } else { nextlevel = levelname; } if (nextSkill != -1) NextSkill = nextSkill; if (flags & CHANGELEVEL_NOINTERMISSION) { level.flags |= LEVEL_NOINTERMISSION; } cluster_info_t *thiscluster = FindClusterInfo (level.cluster); cluster_info_t *nextcluster = nextinfo? FindClusterInfo (nextinfo->cluster) : NULL; startpos = position; gameaction = ga_completed; if (nextinfo != NULL) { if (thiscluster != nextcluster || (thiscluster && !(thiscluster->flags & CLUSTER_HUB))) { if (nextinfo->flags2 & LEVEL2_RESETINVENTORY) { flags |= CHANGELEVEL_RESETINVENTORY; } if (nextinfo->flags2 & LEVEL2_RESETHEALTH) { flags |= CHANGELEVEL_RESETHEALTH; } } } changeflags = flags; bglobal.End(); //Added by MC: // [RH] Give scripts a chance to do something unloading = true; FBehavior::StaticStartTypedScripts (SCRIPT_Unloading, NULL, false, 0, true); unloading = false; STAT_ChangeLevel(nextlevel); if (thiscluster && (thiscluster->flags & CLUSTER_HUB)) { if ((level.flags & LEVEL_NOINTERMISSION) || (nextcluster == thiscluster)) NoWipe = 35; D_DrawIcon = "TELEICON"; } for(int i = 0; i < MAXPLAYERS; i++) { if (playeringame[i]) { player_t *player = &players[i]; // Un-crouch all players here. player->Uncrouch(); // If this is co-op, respawn any dead players now so they can // keep their inventory on the next map. if ((multiplayer || level.flags2 & LEVEL2_ALLOWRESPAWN) && !deathmatch && player->playerstate == PST_DEAD) { // Copied from the end of P_DeathThink [[ player->cls = NULL; // Force a new class if the player is using a random class player->playerstate = PST_REBORN; if (player->mo->special1 > 2) { player->mo->special1 = 0; } // ]] G_DoReborn(i, false); } } } }
void G_InitLevelLocals () { level_info_t *info; BaseBlendA = 0.0f; // Remove underwater blend effect, if any NormalLight.Maps = realcolormaps; // [BB] Instead of just setting the color, we also have to reset Desaturate and build the lights. NormalLight.ChangeColor (PalEntry (255, 255, 255), 0); level.gravity = sv_gravity * 35/TICRATE; level.aircontrol = (fixed_t)(sv_aircontrol * 65536.f); level.teamdamage = teamdamage; level.flags = 0; level.flags2 = 0; info = FindLevelInfo (level.MapName); level.info = info; level.skyspeed1 = info->skyspeed1; level.skyspeed2 = info->skyspeed2; level.skytexture1 = TexMan.GetTexture(info->SkyPic1, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); level.skytexture2 = TexMan.GetTexture(info->SkyPic2, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); level.fadeto = info->fadeto; level.cdtrack = info->cdtrack; level.cdid = info->cdid; level.FromSnapshot = false; if (level.fadeto == 0) { R_SetDefaultColormap (info->FadeTable); if (strnicmp (info->FadeTable, "COLORMAP", 8) != 0) { level.flags |= LEVEL_HASFADETABLE; } /* } else { NormalLight.ChangeFade (level.fadeto); */ } level.airsupply = info->airsupply*TICRATE; level.outsidefog = info->outsidefog; level.WallVertLight = info->WallVertLight*2; level.WallHorizLight = info->WallHorizLight*2; if (info->gravity != 0.f) { level.gravity = info->gravity * 35/TICRATE; } if (info->aircontrol != 0.f) { level.aircontrol = (fixed_t)(info->aircontrol * 65536.f); } if (info->teamdamage != 0.f) { level.teamdamage = info->teamdamage; } G_AirControlChanged (); cluster_info_t *clus = FindClusterInfo (info->cluster); level.partime = info->partime; level.sucktime = info->sucktime; level.cluster = info->cluster; level.clusterflags = clus ? clus->flags : 0; level.flags |= info->flags; level.flags2 |= info->flags2; level.levelnum = info->levelnum; level.Music = info->Music; level.musicorder = info->musicorder; level.LevelName = level.info->LookupLevelName(); level.NextMap = info->NextMap; level.NextSecretMap = info->NextSecretMap; compatflags.Callback(); compatflags2.Callback(); NormalLight.ChangeFade (level.fadeto); level.DefaultEnvironment = info->DefaultEnvironment; level.DefaultSkybox = NULL; }