//************************************************************************** //** //** ## ## ## ## ## #### #### ### ### //** ## ## ## ## ## ## ## ## ## ## #### #### //** ## ## ## ## ## ## ## ## ## ## ## ## ## ## //** ## ## ######## ## ## ## ## ## ## ## ### ## //** ### ## ## ### ## ## ## ## ## ## //** # ## ## # #### #### ## ## //** //** $Id: LevelInfo.vc 2609 2007-08-09 23:25:00Z dj_jl $ //** //** Copyright (C) 1999-2006 Jānis Legzdiņš //** //** This program is free software; you can redistribute it and/or //** modify it under the terms of the GNU General Public License //** as published by the Free Software Foundation; either version 2 //** of the License, or (at your option) any later version. //** //** This program is distributed in the hope that it will be useful, //** but WITHOUT ANY WARRANTY; without even the implied warranty of //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //** GNU General Public License for more details. //** //************************************************************************** class LevelInfo : Thinker native abstract; native readonly GameInfo Game; native readonly WorldInfo World; string LevelName; int LevelNum; byte Cluster; name NextMap; name SecretMap; int ParTime; int SuckTime; int Sky1Texture; int Sky2Texture; float Sky1ScrollDelta; float Sky2ScrollDelta; name SkyBox; name FadeTable; int Fade; int OutsideFog; name SongLump; byte CDTrack; bool bDoubleSky; // parallax sky: sky2 behind sky1 bool bLightning; // Use of lightning on the level flashes from sky1 to sky2 // Special actions, as set in MAPINFO. bool bMap07Special; bool bBaronSpecial; bool bCyberDemonSpecial; bool bSpiderMastermindSpecial; bool bMinotaurSpecial; bool bDSparilSpecial; bool bIronLichSpecial; bool bSpecialActionOpenDoor; bool bSpecialActionLowerFloor; bool bSpecialActionKillMonsters; bool bNoIntermission; bool bAllowMonsterTelefrags; bool bNoAllies; bool bDeathSlideShow; bool bForceNoSkyStretch; bool bLookupName; bool bFallingDamage; bool bOldFallingDamage; bool bStrifeFallingDamage; bool bMonsterFallingDamage; bool bClusterHub; readonly bool bBegunPlay; int TotalKills; int TotalItems; int TotalSecret; // for intermission int CurrentKills; int CurrentItems; int CurrentSecret; float CompletitionTime; // For intermission // Maintain single and multi player starting spots. mthing_t DeathmatchStarts[MAXDEATHMATCHSTARTS]; // Player spawn spots for deathmatch. int NumDeathmatchStarts; mthing_t PlayerStarts[MAX_PLAYER_STARTS * MAXPLAYERS]; // Player spawn spots. int TIDList[MAX_TID_COUNT + 1]; // +1 for termination marker Entity TIDMobj[MAX_TID_COUNT]; float Gravity; // Level Gravity replication { reliable if (Role == ROLE_Authority) LevelName, Cluster, ParTime, SuckTime, Sky1Texture, Sky2Texture, Sky1ScrollDelta, Sky2ScrollDelta, SkyBox, FadeTable, Fade, OutsideFog, SongLump, CDTrack, bDoubleSky, bLightning, bNoIntermission, bForceNoSkyStretch, bLookupName, TotalKills, TotalItems, TotalSecret, CurrentKills, CurrentItems, CurrentSecret, CompletitionTime; } // // Static lights // native final void AddStaticLight(TVec origin, float radius); native final void AddStaticLightRGB(TVec origin, float radius, int colour); // // Sound sequences // native final void SectorStartSequence(sector_t* sector, name sequence, int ModeNum); native final void SectorStopSequence(sector_t* sector); native final void PolyobjStartSequence(polyobj_t* mobj, name sequence, int ModeNum); native final void PolyobjStopSequence(polyobj_t* mobj); // // Exiting the level // native final void ExitLevel(int Position); native final void SecretExitLevel(int Position); native final void Completed(int Map, int Position, int SaveAngle); // // Special thinker utilites // native final void ChangeSwitchTexture(line_t* line, int useAgain, name DefaultSound); native final void ForceLightning(); //========================================================================== // // SpawnSpecials // //========================================================================== void SpawnSpecials() { } //========================================================================== // // UpdateSpecials // //========================================================================== void UpdateSpecials() { } //========================================================================== // // AfterUnarchiveThinkers // //========================================================================== void AfterUnarchiveThinkers() { } //========================================================================== // // FindLine // //========================================================================== line_t* FindLine(int lineTag, int *searchPosition) { return NULL; } //========================================================================== // // PolyThrustMobj // //========================================================================== void PolyThrustMobj(Entity A, TVec thrustDir, polyobj_t * po) { } //========================================================================== // // TagBusy // //========================================================================== bool TagBusy(int tag) { int sectorIndex; for (sectorIndex = XLevel.FindSectorFromTag(tag, -1); sectorIndex >= 0; sectorIndex = XLevel.FindSectorFromTag(tag, sectorIndex)) { if (XLevel.Sectors[sectorIndex].FloorData || XLevel.Sectors[sectorIndex].CeilingData) { return true; } } return false; } //========================================================================== // // PolyBusy // //========================================================================== bool PolyBusy(int polyobj) { return false; } //========================================================================== // // ThingCount // //========================================================================== int ThingCount(int type, int tid) { return 0; } //========================================================================== // // FindMobjFromTID // //========================================================================== Entity FindMobjFromTID(int tid, int *searchPosition) { int i; for (i = *searchPosition + 1; TIDList[i] != 0; i++) { if (TIDList[i] == tid) { *searchPosition = i; return TIDMobj[i]; } } *searchPosition = -1; return none; } //========================================================================== // // ExecuteActionSpecial // //========================================================================== bool ExecuteActionSpecial(int Special, int Arg1, int Arg2, int Arg3, int Arg4, int Arg5, line_t* line, int side, Entity A) { return false; } //========================================================================== // // EV_ThingProjectile // //========================================================================== bool EV_ThingProjectile(int Arg1, int Arg2, int Arg3, int Arg4, int Arg5, bool gravity, int newtid) { return false; } //========================================================================== // // StartPlaneWatcher // //========================================================================== void StartPlaneWatcher(Entity it, line_t* line, int lineSide, bool ceiling, int tag, int height, int special, int arg0, int arg1, int arg2, int arg3, int arg4) { } //========================================================================== // // CreateTIDList // //========================================================================== void CreateTIDList() { int i; Entity mobj; i = 0; foreach AllThinkers(Entity, mobj) { if (mobj.TID != 0) { // Add to list if (i == MAX_TID_COUNT) { Error("P_CreateTIDList: MAX_TID_COUNT exceeded."); } TIDList[i] = mobj.TID; TIDMobj[i++] = mobj; } } // Add termination marker TIDList[i] = 0; } //************************************************************************** //** //** Special thinker utilites. //** //************************************************************************** //========================================================================== // // getNextSector // // Return sector_t * of sector next to current. NULL if not two-sided line // //========================================================================== sector_t *getNextSector(line_t * line, sector_t * sec) { if (!(line->flags & ML_TWOSIDED)) return NULL; if (line->frontsector == sec) return line->backsector; return line->frontsector; } //========================================================================== // // FindLowestFloorSurrounding // // FIND LOWEST FLOOR HEIGHT IN SURROUNDING SECTORS // //========================================================================== float FindLowestFloorSurrounding(sector_t* sec, TVec* v) { int i; line_t* check; sector_t* other; float floor; float ofloor; TVec spot; spot = *sec->lines[0]->v1; floor = GetPlanePointZ(&sec->floor, spot); for (i = 0; i < sec->linecount; i++) { check = sec->lines[i]; other = getNextSector(check, sec); if (!other) continue; ofloor = GetPlanePointZ(&other->floor, *check->v1); if (ofloor < floor && ofloor < GetPlanePointZ(&sec->floor, *check->v1)) { floor = ofloor; spot = *check->v1; } ofloor = GetPlanePointZ(&other->floor, *check->v2); if (ofloor < floor && ofloor < GetPlanePointZ(&sec->floor, *check->v2)) { floor = ofloor; spot = *check->v2; } } if (v) *v = spot; return floor; } //========================================================================== // // FindHighestFloorSurrounding // // FIND HIGHEST FLOOR HEIGHT IN SURROUNDING SECTORS // //========================================================================== float FindHighestFloorSurrounding(sector_t* sec, TVec* v) { int i; line_t* check; sector_t* other; float floor; float ofloor; TVec spot; spot = *sec->lines[0]->v1; floor = -99999.0; for (i = 0; i < sec->linecount; i++) { check = sec->lines[i]; other = getNextSector(check, sec); if (!other) continue; ofloor = GetPlanePointZ(&other->floor, *check->v1); if (ofloor > floor) { floor = ofloor; spot = *check->v1; } ofloor = GetPlanePointZ(&other->floor, *check->v2); if (ofloor > floor) { floor = ofloor; spot = *check->v2; } } if (v) *v = spot; return floor; } //========================================================================== // // FindNextHighestFloor // // Passed a sector, returns the value of the smallest floor height in a // surrounding sector larger than the floor height of passed sector. If no // such height exists the floor height of passed sector is returned. // // Rewritten by Lee Killough to avoid fixed array and to be faster // //========================================================================== float FindNextHighestFloor(sector_t* sec, TVec* v) { int i; line_t* check; sector_t* other; float floor; float ofloor; TVec spot; float height; float heightdiff; spot = *sec->lines[0]->v1; height = GetPlanePointZ(&sec->floor, spot); heightdiff = 99999.0; for (i = 0; i < sec->linecount; i++) { check = sec->lines[i]; other = getNextSector(check, sec); if (!other) continue; ofloor = GetPlanePointZ(&other->floor, *check->v1); floor = GetPlanePointZ(&sec->floor, *check->v1); if (ofloor > floor && ofloor - floor < heightdiff) { heightdiff = ofloor - floor; height = ofloor; spot = *check->v1; } ofloor = GetPlanePointZ(&other->floor, *check->v2); floor = GetPlanePointZ(&sec->floor, *check->v2); if (ofloor > floor && ofloor - floor < heightdiff) { heightdiff = ofloor - floor; height = ofloor; spot = *check->v2; } } if (v) *v = spot; return height; } //========================================================================== // // FindNextLowestFloor // // Passed a sector, returns the value of the largest floor height in a // surrounding sector smaller than the floor height of passed sector. If no // such height exists the floor height of passed sector is returned. // // jff 02/03/98 Twiddled Lee's P_FindNextHighestFloor to make this // //========================================================================== float FindNextLowestFloor(sector_t* sec, TVec* v) { int i; line_t* check; sector_t* other; float floor; float ofloor; TVec spot; float height; float heightdiff; spot = *sec->lines[0]->v1; height = GetPlanePointZ(&sec->floor, spot); heightdiff = 99999.0; for (i = 0; i < sec->linecount; i++) { check = sec->lines[i]; other = getNextSector(check, sec); if (!other) continue; ofloor = GetPlanePointZ(&other->floor, *check->v1); floor = GetPlanePointZ(&sec->floor, *check->v1); if (ofloor < floor && floor - ofloor < heightdiff) { heightdiff = floor - ofloor; height = ofloor; spot = *check->v1; } ofloor = GetPlanePointZ(&other->floor, *check->v2); floor = GetPlanePointZ(&sec->floor, *check->v2); if (ofloor < floor && floor - ofloor < heightdiff) { heightdiff = floor - ofloor; height = ofloor; spot = *check->v2; } } if (v) *v = spot; return height; } //========================================================================== // // FindNextLowestCeiling // // Passed a sector, returns the value of the largest ceiling height in a // surrounding sector smaller than the ceiling height of passed sector. If // no such height exists the ceiling height of passed sector is returned. // // jff 02/03/98 Twiddled Lee's P_FindNextHighestFloor to make this // //========================================================================== float FindNextLowestCeiling(sector_t* sec, TVec* v) { int i; line_t* check; sector_t* other; float ceil; float oceil; TVec spot; float height; float heightdiff; spot = *sec->lines[0]->v1; height = GetPlanePointZ(&sec->ceiling, spot); heightdiff = 99999.0; for (i = 0; i < sec->linecount; i++) { check = sec->lines[i]; other = getNextSector(check, sec); if (!other) continue; oceil = GetPlanePointZ(&other->ceiling, *check->v1); ceil = GetPlanePointZ(&sec->ceiling, *check->v1); if (oceil < ceil && ceil - oceil < heightdiff) { heightdiff = ceil - oceil; height = oceil; spot = *check->v1; } oceil = GetPlanePointZ(&other->ceiling, *check->v2); ceil = GetPlanePointZ(&sec->ceiling, *check->v2); if (oceil < ceil && ceil - oceil < heightdiff) { heightdiff = ceil - oceil; height = oceil; spot = *check->v2; } } if (v) *v = spot; return height; } //========================================================================== // // FindNextHighestCeiling // // Passed a sector, returns the value of the smallest ceiling height in a // surrounding sector larger than the ceiling height of passed sector. If // no such height exists the ceiling height of passed sector is returned. // // jff 02/03/98 Twiddled Lee's P_FindNextHighestFloor to make this // //========================================================================== float FindNextHighestCeiling(sector_t* sec, TVec* v) { int i; line_t* check; sector_t* other; float ceil; float oceil; TVec spot; float height; float heightdiff; spot = *sec->lines[0]->v1; height = GetPlanePointZ(&sec->ceiling, spot); heightdiff = 99999.0; for (i = 0; i < sec->linecount; i++) { check = sec->lines[i]; other = getNextSector(check, sec); if (!other) continue; oceil = GetPlanePointZ(&other->ceiling, *check->v1); ceil = GetPlanePointZ(&sec->ceiling, *check->v1); if (oceil > ceil && oceil - ceil < heightdiff) { heightdiff = oceil - ceil; height = oceil; spot = *check->v1; } oceil = GetPlanePointZ(&other->ceiling, *check->v2); ceil = GetPlanePointZ(&sec->ceiling, *check->v2); if (oceil > ceil && oceil - ceil < heightdiff) { heightdiff = oceil - ceil; height = oceil; spot = *check->v2; } } if (v) *v = spot; return height; } //========================================================================== // // FindLowestCeilingSurrounding // // FIND LOWEST CEILING IN THE SURROUNDING SECTORS // //========================================================================== float FindLowestCeilingSurrounding(sector_t* sec, TVec* v) { int i; line_t* check; sector_t* other; float height; float oceil; TVec spot; spot = *sec->lines[0]->v1; height = 99999.0; for (i = 0; i < sec->linecount; i++) { check = sec->lines[i]; other = getNextSector(check, sec); if (!other) continue; oceil = GetPlanePointZ(&other->ceiling, *check->v1); if (oceil < height) { height = oceil; spot = *check->v1; } oceil = GetPlanePointZ(&other->ceiling, *check->v2); if (oceil < height) { height = oceil; spot = *check->v2; } } if (v) *v = spot; return height; } //========================================================================== // // FindHighestCeilingSurrounding // // FIND HIGHEST CEILING IN THE SURROUNDING SECTORS // //========================================================================== float FindHighestCeilingSurrounding(sector_t* sec, TVec* v) { int i; line_t* check; sector_t* other; float height; float oceil; TVec spot; spot = *sec->lines[0]->v1; height = -99999.0; for (i = 0; i < sec->linecount; i++) { check = sec->lines[i]; other = getNextSector(check, sec); if (!other) continue; oceil = GetPlanePointZ(&other->ceiling, *check->v1); if (oceil > height) { height = oceil; spot = *check->v1; } oceil = GetPlanePointZ(&other->ceiling, *check->v2); if (oceil > height) { height = oceil; spot = *check->v2; } } if (v) *v = spot; return height; } //========================================================================== // // FindShortestTextureAround // // Passed a sector number, returns the shortest lower texture on a // linedef bounding the sector. // // jff 02/03/98 Add routine to find shortest lower texture // //========================================================================== float FindShortestTextureAround(sector_t* sec) { int i; float minsize; int texnum; minsize = 99999.0; for (i = 0; i < sec->linecount; i++) { if (!(sec->lines[i]->flags & ML_TWOSIDED)) continue; texnum = XLevel.Sides[sec->lines[i]->sidenum[0]].bottomtexture; if (texnum >= 0) { if (TextureHeight(texnum) < minsize) { minsize = TextureHeight(texnum); } } texnum = XLevel.Sides[sec->lines[i]->sidenum[1]].bottomtexture; if (texnum >= 0) { if (TextureHeight(texnum) < minsize) { minsize = TextureHeight(texnum); } } } return minsize < 99999.0 ? minsize : TextureHeight(0); } //========================================================================== // // FindShortestUpperAround // // Passed a sector number, returns the shortest upper texture on a // linedef bounding the sector. // // Note: If no upper texture exists MAXINT is returned. // // jff 03/20/98 Add routine to find shortest upper texture // //========================================================================== float FindShortestUpperAround(sector_t* sec) { int i; float minsize; int texnum; minsize = 99999.0; for (i = 0; i < sec->linecount; i++) { if ((sec->lines[i]->flags & ML_TWOSIDED)) continue; texnum = XLevel.Sides[sec->lines[i]->sidenum[0]].toptexture; if (texnum >= 0) { if (TextureHeight(texnum) < minsize) { minsize = TextureHeight(texnum); } } texnum = XLevel.Sides[sec->lines[i]->sidenum[1]].toptexture; if (texnum >= 0) { if (TextureHeight(texnum) < minsize) { minsize = TextureHeight(texnum); } } } return minsize < 99999.0 ? minsize : TextureHeight(0); } //========================================================================== // // FindModelFloorSector // // Passed a floor height and a sector number, return a pointer to a // a sector with that floor height across the lowest numbered two sided // line surrounding the sector. // // Note: If no sector at that height bounds the sector passed, return NULL // // jff 02/03/98 Add routine to find numeric model floor // around a sector specified by sector number // jff 3/14/98 change first parameter to plain height to allow call // from routine not using floormove_t // //========================================================================== sector_t* FindModelFloorSector(sector_t* sec, float height) { int i; line_t* check; sector_t* other; //jff 5/23/98 don't disturb sec->linecount while searching // but allow early exit in old demos for (i = 0; i < sec->linecount; i++) { check = sec->lines[i]; other = getNextSector(check, sec); if (other && (GetPlanePointZ(&other->floor, *check->v1) == height || GetPlanePointZ(&other->floor, *check->v2) == height)) { return other; } } return NULL; } //========================================================================== // // FindModelCeilingSector // // Passed a ceiling height and a sector number, return a pointer to a // a sector with that ceiling height across the lowest numbered two sided // line surrounding the sector. // // Note: If no sector at that height bounds the sector passed, return NULL // // jff 02/03/98 Add routine to find numeric model ceiling // around a sector specified by sector number // used only from generalised ceiling types // jff 3/14/98 change first parameter to plain height to allow call // from routine not using ceiling_t // //========================================================================== sector_t* FindModelCeilingSector(sector_t* sec, float height) { int i; line_t* check; sector_t* other; //jff 5/23/98 don't disturb sec->linecount while searching // but allow early exit in old demos for (i = 0; i < sec->linecount; i++) { check = sec->lines[i]; other = getNextSector(check, sec); if (other && (GetPlanePointZ(&other->ceiling, *check->v1) == height || GetPlanePointZ(&other->ceiling, *check->v2) == height)) { return other; } } return NULL; } //========================================================================== // // FindMinSurroundingLight // // Find minimum light from an adjacent sector // //========================================================================== int FindMinSurroundingLight(sector_t* sector, int min) { int i; line_t* line; sector_t* check; for (i = 0; i < sector->linecount; i++) { line = sector->lines[i]; check = getNextSector(line, sector); if (!check) continue; if (check->params.lightlevel < min) min = check->params.lightlevel; } return min; } //========================================================================== // // FindHighestFloorPoint // // Find the highest point on the floor of the sector // //========================================================================== float FindHighestFloorPoint(sector_t* sec, TVec* v) { int i; line_t* line; float height; float probeheight; TVec spot; if (!sec->floor.normal.x && !sec->floor.normal.y) { if (v) *v = *sec->lines[0]->v1; return sec->floor.dist; } height = -99999.0; for (i = 0; i < sec->linecount; i++) { line = sec->lines[i]; probeheight = GetPlanePointZ(&sec->floor, *line->v1); if (probeheight > height) { height = probeheight; spot = *line->v1; } probeheight = GetPlanePointZ(&sec->floor, *line->v2); if (probeheight > height) { height = probeheight; spot = *line->v2; } } if (v) *v = spot; return height; } //========================================================================== // // FindLowestCeilingPoint // // Find the lowest point on the ceiling of the sector // //========================================================================== float FindLowestCeilingPoint(sector_t* sec, TVec* v) { int i; line_t* line; float height; float probeheight; TVec spot; if (!sec->ceiling.normal.x && !sec->ceiling.normal.y) { if (v) *v = *sec->lines[0]->v1; return -sec->ceiling.dist; } height = 99999.0; for (i = 0; i < sec->linecount; i++) { line = sec->lines[i]; probeheight = GetPlanePointZ(&sec->ceiling, *line->v1); if (probeheight < height) { height = probeheight; spot = *line->v1; } probeheight = GetPlanePointZ(&sec->ceiling, *line->v2); if (probeheight < height) { height = probeheight; spot = *line->v2; } } if (v) *v = spot; return height; } //========================================================================== // // SpawnMapThing // //========================================================================== void SpawnMapThing(mthing_t* mthing) { } //========================================================================== // // CopyMThing // //========================================================================== void CopyMThing(mthing_t * from, mthing_t * to) { to->tid = from->tid; to->x = from->x; to->y = from->y; to->height = from->height; to->angle = from->angle; to->type = from->type; to->options = from->options; to->special = from->special; to->arg1 = from->arg1; to->arg2 = from->arg2; to->arg3 = from->arg3; to->arg4 = from->arg4; to->arg5 = from->arg5; } //========================================================================== // // UpdateParticle // //========================================================================== void UpdateParticle(particle_t* p, float DeltaTime) { } defaultproperties { bAlwaysRelevant = true; }