| 226 | } |
| 227 | |
| 228 | void parseOMWScripts(ESM::LuaScriptsCfg& cfg, std::string_view data) |
| 229 | { |
| 230 | while (!data.empty()) |
| 231 | { |
| 232 | // Get next line |
| 233 | std::string_view line = data.substr(0, data.find('\n')); |
| 234 | data = data.substr(std::min(line.size() + 1, data.size())); |
| 235 | if (!line.empty() && line.back() == '\r') |
| 236 | line = line.substr(0, line.size() - 1); |
| 237 | |
| 238 | while (!line.empty() && isSpace(line[0])) |
| 239 | line = line.substr(1); |
| 240 | if (line.empty() || line[0] == '#') // Skip empty lines and comments |
| 241 | continue; |
| 242 | while (!line.empty() && isSpace(line.back())) |
| 243 | line = line.substr(0, line.size() - 1); |
| 244 | |
| 245 | if (!Misc::StringUtils::ciEndsWith(line, ".lua")) |
| 246 | throw std::runtime_error( |
| 247 | std::format("Lua script should have suffix '.lua', got: {}", line.substr(0, 300))); |
| 248 | |
| 249 | // Split tags and script path |
| 250 | size_t semicolonPos = line.find(':'); |
| 251 | if (semicolonPos == std::string_view::npos) |
| 252 | throw std::runtime_error(std::format("No flags found in: {}", line)); |
| 253 | std::string_view tagsStr = line.substr(0, semicolonPos); |
| 254 | std::string_view scriptPath = line.substr(semicolonPos + 1); |
| 255 | while (!scriptPath.empty() && isSpace(scriptPath[0])) |
| 256 | scriptPath = scriptPath.substr(1); |
| 257 | |
| 258 | ESM::LuaScriptCfg& script = cfg.mScripts.emplace_back(); |
| 259 | script.mScriptPath = VFS::Path::Normalized(scriptPath); |
| 260 | script.mFlags = 0; |
| 261 | |
| 262 | // Parse tags |
| 263 | size_t tagsPos = 0; |
| 264 | while (true) |
| 265 | { |
| 266 | while (tagsPos < tagsStr.size() && (isSpace(tagsStr[tagsPos]) || tagsStr[tagsPos] == ',')) |
| 267 | tagsPos++; |
| 268 | size_t startPos = tagsPos; |
| 269 | while (tagsPos < tagsStr.size() && !isSpace(tagsStr[tagsPos]) && tagsStr[tagsPos] != ',') |
| 270 | tagsPos++; |
| 271 | if (startPos == tagsPos) |
| 272 | break; |
| 273 | std::string_view tagName = tagsStr.substr(startPos, tagsPos - startPos); |
| 274 | auto it = flagsByName.find(tagName); |
| 275 | auto typesIt = typeTagsByName.find(tagName); |
| 276 | if (it != flagsByName.end()) |
| 277 | script.mFlags |= it->second; |
| 278 | else if (typesIt != typeTagsByName.end()) |
| 279 | script.mTypes.push_back(typesIt->second); |
| 280 | else |
| 281 | throw std::runtime_error(std::format("Unknown tag '{}' in: {}", tagName, line)); |
| 282 | } |
| 283 | } |
| 284 | } |
| 285 | |