engine: reject mbf21 and shit24 wads. there is no way to know if it is safe to ignore...
[k8vavoom.git] / source / lockdefs.cpp
blobf66e6ed679eb9e4c17a58cf4cc2fa16b93ca6d67
1 //**************************************************************************
2 //**
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
9 //**
10 //** Copyright (C) 1999-2006 Jānis Legzdiņš
11 //** Copyright (C) 2018-2023 Ketmar Dark
12 //**
13 //** This program is free software: you can redistribute it and/or modify
14 //** it under the terms of the GNU General Public License as published by
15 //** the Free Software Foundation, version 3 of the License ONLY.
16 //**
17 //** This program is distributed in the hope that it will be useful,
18 //** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 //** GNU General Public License for more details.
21 //**
22 //** You should have received a copy of the GNU General Public License
23 //** along with this program. If not, see <http://www.gnu.org/licenses/>.
24 //**
25 //**************************************************************************
26 #include "gamedefs.h"
27 #include "lockdefs.h"
28 #include "decorate/vc_decorate.h"
31 static VLockDef *LockDefs[256];
34 //==========================================================================
36 // ParseLockDefs
38 //==========================================================================
39 static void ParseLockDefs (VScriptParser *sc) {
40 while (!sc->AtEnd()) {
41 if (sc->Check("ClearLocks")) {
42 for (int i = 0; i < 256; ++i) {
43 if (LockDefs[i]) {
44 delete LockDefs[i];
45 LockDefs[i] = nullptr;
48 continue;
51 if (sc->Check("Lock")) {
52 const VTextLocation loc = sc->GetLoc();
53 // lock number
54 sc->ExpectNumber();
55 const int Lock = sc->Number;
56 if (Lock <= 0 || Lock > 255) sc->Error(va("Bad lock number (%d)", sc->Number));
58 VLockDef *LDef = new VLockDef;
59 LDef->MapColor = 0;
60 LDef->LockedSound = "misc/keytry";
61 vuint32 GameFilter = 0;
63 // parse game specifier
64 for (;;) {
65 const vuint32 ngf = SC_ParseGameDef(sc);
66 if (!ngf) break;
67 GameFilter |= ngf;
69 const bool validLock = (GameFilter == 0 || (GameFilter&GGameInfo->GameFilterFlag) != 0);
71 sc->Expect("{");
72 while (!sc->Check("}")) {
73 if (sc->Check("Message")) {
74 sc->ExpectString();
75 LDef->Message = sc->String;
76 continue;
78 if (sc->Check("RemoteMessage")) {
79 sc->ExpectString();
80 LDef->RemoteMessage = sc->String;
81 continue;
83 if (sc->Check("MapColor")) {
84 sc->ExpectNumber();
85 int r = clampToByte(sc->Number);
86 sc->ExpectNumber();
87 int g = clampToByte(sc->Number);
88 sc->ExpectNumber();
89 int b = clampToByte(sc->Number);
90 LDef->MapColor = 0xff000000|(r<<16)|(g<<8)|b;
91 continue;
93 if (sc->Check("LockedSound")) {
94 sc->ExpectString();
95 LDef->LockedSound = *sc->String;
96 continue;
98 if (sc->Check("Any")) {
99 sc->Expect("{");
100 VLockGroup &Grp = LDef->Locks.Alloc();
101 while (!sc->Check("}")) {
102 sc->ExpectString();
103 if (validLock) {
104 VClass *Cls = VClass::FindClassNoCase(*sc->String);
105 if (!Cls) {
106 GCon->Logf(NAME_Warning, "%s: No lockdef class '%s'", *sc->GetLoc().toStringNoCol(), *sc->String);
107 } else {
108 Grp.AnyKeyList.Append(Cls);
112 continue;
114 sc->ExpectString();
115 if (validLock) {
116 VClass *Cls = VClass::FindClassNoCase(*sc->String);
117 if (!Cls) {
118 GCon->Logf(NAME_Warning, "%s: No lockdef class '%s'", *sc->GetLoc().toStringNoCol(), *sc->String);
119 } else {
120 LDef->Locks.Alloc().AnyKeyList.Append(Cls);
125 // copy message if other one is not defined
126 if (LDef->Message.IsEmpty()) LDef->Message = LDef->RemoteMessage;
127 if (LDef->RemoteMessage.IsEmpty()) LDef->RemoteMessage = LDef->Message;
129 // remove lock for another game
130 if (!validLock) {
131 GCon->Logf(NAME_Init, "%s: skipped lock #%d for another game", *loc.toStringNoCol(), Lock);
132 delete LDef;
133 } else {
134 if (LockDefs[Lock]) delete LockDefs[Lock];
135 LockDefs[Lock] = LDef;
138 continue;
141 sc->Error(va("invalid lockdef command (%s)", *sc->String));
143 delete sc;
147 //==========================================================================
149 // InitLockDefs
151 //==========================================================================
152 void InitLockDefs () {
153 for (auto &&it : WadNSNameIterator(NAME_lockdefs, WADNS_Global)) {
154 const int Lump = it.lump;
155 GCon->Logf(NAME_Init, "Parsing lockdefs from '%s'", *W_FullLumpName(Lump));
156 ParseLockDefs(VScriptParser::NewWithLump(Lump));
161 //==========================================================================
163 // ShutdownLockDefs
165 //==========================================================================
166 void ShutdownLockDefs () {
167 for (int i = 0; i < 256; ++i) {
168 if (LockDefs[i]) {
169 delete LockDefs[i];
170 LockDefs[i] = nullptr;
176 //==========================================================================
178 // GetLockDef
180 //==========================================================================
181 VLockDef *GetLockDef (int Lock) {
182 return (Lock < 0 || Lock > 255 ? nullptr : LockDefs[Lock]);