diff --git a/include/common/settings.hh b/include/common/settings.hh index 513752dd..674502ee 100644 --- a/include/common/settings.hh +++ b/include/common/settings.hh @@ -640,6 +640,30 @@ protected: public: using setting_vec3::setting_vec3; + + // allow mangle to only specify pitch, or pitch yaw + bool parse(const std::string &settingName, parser_base_t &parser, source source) override + { + qvec3d vec {}; + + for (int i = 0; i < 3; i++) { + if (!parser.parse_token(PARSE_PEEK)) { + break; + } + + try { + vec[i] = std::stod(parser.token); + } catch (std::exception &) { + break; + } + + parser.parse_token(); + } + + setValue(vec, source); + + return true; + } }; class setting_color : public setting_vec3 @@ -680,6 +704,12 @@ public: }; // settings dictionary +enum class setting_error +{ + NONE, + MISSING, + INVALID +}; class setting_container { @@ -755,7 +785,7 @@ public: return nullptr; } - inline void setSetting(const std::string &name, const std::string &value, source source) + inline setting_error setSetting(const std::string &name, const std::string &value, source source) { setting_base *setting = findSetting(name); @@ -763,11 +793,11 @@ public: if (source == source::COMMANDLINE) { throw parse_exception(fmt::format("Unrecognized command-line option '{}'\n", name)); } - return; + return setting_error::MISSING; } parser_t p{value, { }}; - setting->parse(name, p, source); + return setting->parse(name, p, source) ? setting_error::NONE : setting_error::INVALID; } inline void setSettings(const entdict_t &epairs, source source) diff --git a/include/light/light.hh b/include/light/light.hh index d7a73d91..2d059973 100644 --- a/include/light/light.hh +++ b/include/light/light.hh @@ -306,6 +306,7 @@ public: /* Q2 surface lights (mxd) */ setting_scalar surflightscale{this, "surflightscale", 1.0, &worldspawn_group}; + setting_scalar surflightskyscale{this, "surflightskyscale", 1.0, &worldspawn_group}; setting_scalar surflightsubdivision{this, {"surflightsubdivision", "choplight"}, 16.0, 1.0, 8192.0, &worldspawn_group}; // "choplight" - arghrad3 name diff --git a/light/entities.cc b/light/entities.cc index 37ff1674..324013bc 100644 --- a/light/entities.cc +++ b/light/entities.cc @@ -784,7 +784,9 @@ void LoadEntities(const settings::worldspawn_keys &cfg, const mbsp_t *bsp) /* handle worldspawn */ for (const auto &epair : WorldEnt()) { - light_options.setSetting(epair.first, epair.second, settings::source::MAP); + if (light_options.setSetting(epair.first, epair.second, settings::source::MAP) == settings::setting_error::INVALID) { + logging::print("WARNING: worldspawn key {} has invalid value of \"{}\"\n", epair.first, epair.second); + } } /* apply side effects of settings (in particular "dirt") */ diff --git a/light/light.cc b/light/light.cc index 1f688c7a..c828386e 100644 --- a/light/light.cc +++ b/light/light.cc @@ -1195,6 +1195,9 @@ int light_main(int argc, const char **argv) if (!light_options.surflightscale.isChanged()) { light_options.surflightscale.setValue(0.65, settings::source::GAME_TARGET); } + if (!light_options.surflightskyscale.isChanged()) { + light_options.surflightskyscale.setValue(0.65, settings::source::GAME_TARGET); + } if (!light_options.bouncescale.isChanged()) { light_options.bouncescale.setValue(1.25, settings::source::GAME_TARGET); } diff --git a/light/ltface.cc b/light/ltface.cc index 271d6121..9777dd7e 100644 --- a/light/ltface.cc +++ b/light/ltface.cc @@ -1607,11 +1607,11 @@ inline qvec3f BounceLight_ColorAtDist(const settings::worldspawn_keys &cfg, floa // mxd. Surface light falloff. Returns color in [0,255] inline qvec3f SurfaceLight_ColorAtDist( - const settings::worldspawn_keys &cfg, const float &intensity, const qvec3d &color, const float &dist) + const settings::worldspawn_keys &cfg, const float &surf_scale, const float &intensity, const qvec3d &color, const float &dist) { // Exponential falloff const float d = max(dist, 16.0f); // Clamp away hotspots, also avoid division by 0... - const float scaledintensity = intensity * cfg.surflightscale.value(); + const float scaledintensity = intensity * surf_scale; const float scale = (1.0f / (d * d)); return color * scaledintensity * scale; @@ -1673,7 +1673,7 @@ inline qvec3f GetSurfaceLighting(const settings::worldspawn_keys &cfg, const sur } // Get light contribution - result = SurfaceLight_ColorAtDist(cfg, vpl->intensity, vpl->color, dist); + result = SurfaceLight_ColorAtDist(cfg, vpl->omnidirectional ? cfg.surflightskyscale.value() : cfg.surflightscale.value(), vpl->intensity, vpl->color, dist); // Apply angle scale const qvec3f resultscaled = result * dotProductFactor; @@ -1713,7 +1713,7 @@ SurfaceLight_SphereCull(const surfacelight_t *vpl, const lightsurf_t *lightsurf, const float dist = qv::length(dir) + lightsurf->extents.radius; // Get light contribution - const qvec3f color = SurfaceLight_ColorAtDist(cfg, vpl->totalintensity, vpl->color, dist); + const qvec3f color = SurfaceLight_ColorAtDist(cfg, vpl->omnidirectional ? cfg.surflightskyscale.value() : cfg.surflightscale.value(), vpl->totalintensity, vpl->color, dist); return qv::gate(color, (float) bouncelight_gate); }