From c484fab32dcac655164f082805d1d55d1d058f2f Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Tue, 26 Mar 2024 07:31:33 +1100 Subject: [PATCH] experiment: auto-conversion of object spread lights to hybrid spread/point lights --- assets/opensb/font/dotsies.woff2 | Bin 0 -> 6716 bytes assets/opensb/objects/opensb/object.patch.lua | 19 +------ .../opensb/scripts/opensb/assets/postload.lua | 10 ++-- source/base/StarCellularLightArray.cpp | 49 +++++++++++++----- source/base/StarCellularLightArray.hpp | 1 + source/base/StarCellularLighting.cpp | 6 +-- source/base/StarCellularLighting.hpp | 2 +- source/game/StarItemDrop.cpp | 2 +- source/game/StarLightSource.cpp | 10 +++- source/game/StarLightSource.hpp | 12 ++++- source/game/StarNetworkedAnimator.cpp | 2 +- source/game/StarObject.cpp | 2 +- source/game/StarObjectDatabase.cpp | 5 +- source/game/StarObjectDatabase.hpp | 2 +- source/game/StarProjectile.cpp | 4 +- source/game/StarProjectileDatabase.cpp | 5 +- source/game/StarProjectileDatabase.hpp | 2 +- source/game/StarWorldClient.cpp | 11 ++-- source/game/StarWorldImpl.hpp | 6 +-- source/game/items/StarInspectionTool.cpp | 2 +- source/game/items/StarTools.cpp | 2 +- .../scripting/StarLuaAnimationComponent.hpp | 2 +- 22 files changed, 95 insertions(+), 61 deletions(-) create mode 100644 assets/opensb/font/dotsies.woff2 diff --git a/assets/opensb/font/dotsies.woff2 b/assets/opensb/font/dotsies.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..853124b9051408e5ccc912a27de22bbbb51832d5 GIT binary patch literal 6716 zcmV-C8pGvxPew8T0RR9102(|14FCWD07JY002$%{0RR9100000000000000000000 z0000#Mn+Uk90p(jggOWW5eN#}WW+iPgC+n0HUcCAhDZb;1(baUg-aU+HZ?NOlKgH5 zN?O>xfQX9Cg4zH7A%TwTl^xMfkb!uIH;2qYY@u)}cQxCCPKAtck%pJw#4RXFf{;w_ zcjXnI+dbSX4zn|74xq{9Qy#h|sQ=(+=;)PGW1TS)&oy{{PVc=R2ZCClP>LtPERc_T zFe@HhQW1lu;ySi5b1F>4fS&$hyYGY9p+=e}bl6O39_+pQWs~_o3o`{)`)W*usRo`& z@_)9?ZV5GzCk1$?P@=FE?ogc)_kV5vOIH6J<}agFQKTk9mJO{(A*K+qXE73gCil)% zc10%Kg49F10De$6bG*PrtD@^vbDdVdNGQkCi-JR(0XyUD-dM2nK<#y>9B7%kC3^H* zxA_G@NJwyV2AseDf6Y&uo1YYjv*h+vm@MjoFjXwft2`=qE9gZ0sv2zH_HIvzNVc5z>H^ACpaXA{E7?E?Q{mfTG=!C20laxQ1BS6 zFF6cc@HD1XM_1xDBocqdXTb+5ju__wC;%|7%#Q#G2mpq$jdC=IFBAT0j6*B{L_q;A zCX;yH}F0_!%ufcmspW75=-((DXAn)WPo0|JKI2FA+bJ6F7f*+^umkQT5YAJ zn$@dhRH|5^e7Pe1)(2IWTY9O*7W_Z{`|7`!bIrN>Ty3s87oF2Vu&yOMjB+rc4s_9j_dhB7{v*IFNDNWRa7@^r;T+! z#MBStWVE1ARa9J3T85_P*0$cE@nxFjD_5*qvu^GB4VyM@-m-Q3wjH~6?%O*xjVb`Z zB+5|@vJ)Qjn=o=jy0rY(b z;20TQ27oL?Jo#qtL<^9^fUXx{Xj&Vj0f1L|m~NQVQ#64n+PjP^3VoB!M9~FvcJT?z zrcs0`hMCM|P-GK|M2ZHJ#{mK0Tz$kV%ECX-417EWn`qIgPe%g<2B4T ztQS?C0041!Db&%5z!xMrCf}fYn)x@HmJD2Rtc5M>jj~K2<}4^soxH6b9g5xYdh%~6 z8-vx<3PKlZqwX7jOOQ%2_Bsid4D62rky8oC9Afx~P z*`4Lk8%-xa1VE9$qgu1;B%Zc?_AUQYL_-_7XL<`ZNMvk}zAMWZea|?V@@_=TS;ulsRW0!#25(R+oevVSnEa0$D$2Z{Ld1Z(2;Eba&2M zFZb+X$TCR>9O1g_0=b=j!wtaOy+8+UTVSVnlJt|Q~S}T^}>VKd1tiRYK!nccyp~`HlKI3Ji*$xWPWK=)Tj$D0+3cvriQZW=V&6e%+ z;N%!q-c3^@TZYr%=F+7W$A2Co+75O^E}nC{V4K%545u6@1#+YpMRA2d`2>ftxUH?W ztocsph|Aha(r)Sc@f8jUt)8%w` zcJ9;C&9v=X9yF=U*kntc?`! z*U!$(d7*{oj$w8=KxsUwS3l3*{mCorq)!2muv|TUx;z)}%zHbjDhwXk8Es|f^ zo?3cKH;;(u3{v_o8SwvueR+;Y4UT^2FjGC_^}{2XQMW;jejlfln{h*WgO|aSiu?3y z4LaQ$5`Mc-nZm5CFx)15);h!{1gc9#*j~JLO8&MA@5M5#D++o;^zMGxEQ^# z$&u1$5{s4n%la){1EN2RMAYb!!+z|kV?k!?%zT%aU6igpU>fD1FpTELNZee&kJgKs zb^kf^kJy+)%66w>10|PTuycWJ9v#?xW9M&$tNa?vb_aT-@QQXXU**Is-I#Mo==_+O z+F%>;Gh=BL<*W=y_{cZ%R%GUb=#zK^ThupS^igo`Z5b$5;uL?XPKDjfX;~P5VygfhSZN@z+BoGZ?`Y9 zuhpSer77X`rTO?na3N;&w7^-crZ0AUuV!rfeCOk#aW)E-N&xqXf(lT+nok|v0y zDp6IDbB(k2b94PlrW(ltp&kz`EfbX%JH|Tsv%U^$opB7UldV!+_b-1??(YrtafM^T z*IzitH}nifc-61asFtX7k_e%MJWE0MAu3(k%BFaun-Qay814SsB;p!G=!EJ&^NH&% zt_>{~lE}~|dvADbSm#@hNGNQwD%}>_s-72ZO|Zyre8S;xG;9gbo~HaV=p_X9zihswlwWWzc{NR zD-#!We5za6{@mI-0ad?PIrWLMX24Yxg}QgK|j+J zb35;e|AdIDmheg)zp`X~!yW7~pXO6rZ4$pf+(}0ekiJBk>fw2FCa@;AR_QEqGS4KD z+-omS{r6H{Q&S(GJ*o(=SRdvS*4|##y+`J7=xDfs6nkNzy8aC zXMzFK`_A8UyIV+_!Yw+}p~=V7pj487#JNj(ql*$cl#1?EIxS{ zTevA?$pv^`-p-gh``&m*Zl4cNw4Ag1EI2OP1?_*UOVns+22`!UCH*g2bhq7GuD{4% zxW3gO|F_Wm#7&=&H{N@CPM^lPC571Jc&>bIV)Xf%oJ@DGqOOs4sWkh{n*(2CrgnSW zDcjSBj!K5jt6O&Yhc>>wLa&S}m^izdu`ciMT?e9SLR^h>oUMX61v)i80o6-od(DJN zfXGG)oc{xnu$=rMTWKDK5(QQ0Ul2P@f+Qh6)^GwNv|X(DIdbTHBwv zQacs&F!5_3&%73^onmh^|}CT%Y1mrdlK!_Ku@BFVR|3sBg` zGch(-T)xoEPNXt`qcS3jR~>mpB>2fcmMOs9XfM}$ZGPfA{pzq&Nd z&Sw$JPvj>qV*S$W58oZe3zEAc!mDihtb4;NyTg-ky22$Q$|GA?EG+TJj)<&S4C_5r zm;R+}b94(?ITyTBCt0`sTnt^8Hf3%?^7=IQYuAO+)4p|Hb$|IJdOOA-QxX>^lbmK9 z;|!z4F|JA{h?SpvzF6jgpZ)AcMJM@H-`a;u9@b2cv-Tz)7`x@No;$Q z3n+8mv6gD5-fSgvk8Q_)b&rfvjs|`ws=H5V*DO#%DP)G+I4``RPe@P z>T#O9^jcN$+Va9rm#JU-9WIh+r%M=zDX||)UxET$+ELtiC6vIkI$hX{Q))E? z#h}D|$ddDfYz=5gp>9V$QR(BpLmwHne^BwF*i?U@) ziiatijYEIG;>U}){^1?sn4d#C&IRWO<)i6Cx|7P-iHK=}eVtvc_8cZ(f6{Pg9-~mT zAH|2)Pte~6_0>?6hvV8?p%3z|D{B=`(RnoKSqu%yR~fe>`L4}w~b0z_&r$_}L0s!97e+xr!0VA@QaYYY? z=s~&%^^np)1_%Qo6O0Ga!H^Ng3rY|&z{tTaERaD)hGF>BhH*nXBB($8%LY2>C3+EO z)Q}(OYv_c4d`-VwNKZpJ%+H^em7Gwkzl1|%4bx%Z5b(W&d~ylzGXmt0b>sp4T`So| zLg>HRiH4NZA2pF~(o3IV(k&#PKEwtG$#Qxdtt6kECfBjq)ijKLjm_3ErQ}QOw1AP4 zpImW}u_J%jU>4&~o@1MFOdRw{YdIptLKx9li4w*tO(rNUQ=hU8=fT6#m)=WPp z9i&6_JhV339@l#qwt=ppXRuri>7w_r(;~WqPM;z04n51~;5+#l9{1zWvkcwO!WBU&(BS|8UX6P?A#dZt-X1!o95Da^C;)%}s$r-{ z#epRe+5-sIqrFKw;fR$;HbCaYL%FaJY*{5#RE>JZ0zFiVdQyii{wKQK91iX}y2=06 z$Wf>++USaUau;C$Lm-C`NQ87yLI$vB$C2yUvayQxpq;AF0cUN%@HTwwu@AsTDc9XN1jo}-Y-!iFuw=ov>hJ%BUzdAjI6u3ITOo5Pw;Z9_m0 ziYmjRGPY7hwRF$l1TxXF22@X|B#TVibgG_JkH_c=JrmgNb-1P$5;9Iwz1?~upZX$) zTt_PhXy*V;WP!=!qc%)(5}n0n6tEMnyc9N^+vw&1+ZKo^H=&Xy<-V(f$fcoWlb0RR*L0RfQo^*bG_s*NbTA7?yEAw# z3U0<{@4>N|A264rH8DStJuAjpWJ4Z1F+7CwNbKyxq!`WeF_MW2%FRc}6Do_%8IxaS zG*RQ~$kmio#g9sX2#rA(3Q4O71EhtP5fI6ObHQ1-Fva$yf;Q5_0@}S`O_XOg8*rkf!k*O&N?VMGAEd^z$Q_i3}!Stm#pb}P6~ov zh`{C^9;eEGjWLrg>lO>n9t%dIXY_>ghp6f#g|<&&Fgw7KZ#&NyHY1gmoPiu4Y* zM7xO!K+G7>M=yiplYdu5S74RVS5s)%AQvM>Kj7&kE;IL}3w6AJ4C1_NFb)nN%@v^)3@c^O#3meTZN@ zz1IR0s+JULfx3WDxsg8?+HF?ce3Bl&r4$zbW2cx|FQfq8Hrto9B9^0sz*% zCc?+$u4e3g-pB1b%aUzv9DQA7pPRO`cH!O4r?v29Z~Nq9OZ;er=U=gv!8`;&=GG~SDv2AZ zA?uk&WmgdkqjTQG)k%Qei%v})VI4Yk>DJ@n>E+G451+n#`|<0~KL`wg!r%xb3XQ?y z@B|`>TxoYz~*l7YIdS32s4 void CellularLightArray::calculatePointLighting(size_t xmin, size_t ymin, size_t xmax, size_t ymax) { - float perBlockObstacleAttenuation = 1.0f / m_pointMaxObstacle; - float perBlockAirAttenuation = 1.0f / m_pointMaxAir; + float pointPerBlockObstacleAttenuation = 1.0f / m_pointMaxObstacle; + float pointPerBlockAirAttenuation = 1.0f / m_pointMaxAir; for (PointLight light : m_pointLights) { if (light.position[0] < 0 || light.position[0] > m_width - 1 || light.position[1] < 0 || light.position[1] > m_height - 1) @@ -14,8 +15,10 @@ void CellularLightArray::calculatePointLighting(size_t xmin, float maxIntensity = ScalarLightTraits::maxIntensity(light.value); Vec2F beamDirection = Vec2F(1, 0).rotate(light.beamAngle); + float perBlockObstacleAttenuation = light.asSpread ? 1.0f / m_spreadMaxObstacle : pointPerBlockObstacleAttenuation; + float perBlockAirAttenuation = light.asSpread ? 1.0f / m_spreadMaxAir : pointPerBlockAirAttenuation; - float maxRange = maxIntensity * m_pointMaxAir; + float maxRange = maxIntensity * (light.asSpread ? m_spreadMaxAir : m_pointMaxAir); // The min / max considering the radius of the light size_t lxmin = std::floor(std::max(xmin, light.position[0] - maxRange)); size_t lymin = std::floor(std::max(ymin, light.position[1] - maxRange)); @@ -40,7 +43,7 @@ void CellularLightArray::calculatePointLighting(size_t xmin, continue; Vec2F direction = relativeLightPosition / distance; - if (light.beam > 0.0f) { + if (light.beam > 0.0001f) { attenuation += (1.0f - light.beamAmbience) * clamp(light.beam * (1.0f - direction * beamDirection), 0.0f, 1.0f); if (attenuation >= 1.0f) continue; @@ -54,12 +57,21 @@ void CellularLightArray::calculatePointLighting(size_t xmin, float circularizedPerBlockObstacleAttenuation = perBlockObstacleAttenuation / max(fabs(direction[0]), fabs(direction[1])); float blockAttenuation = lineAttenuation(blockPos, light.position, circularizedPerBlockObstacleAttenuation, remainingAttenuation); + attenuation += blockAttenuation; // Apply single obstacle boost (determine single obstacle by one // block unit of attenuation). - attenuation += blockAttenuation + min(blockAttenuation, circularizedPerBlockObstacleAttenuation) * m_pointObstacleBoost; + if (!light.asSpread) + attenuation += min(blockAttenuation, circularizedPerBlockObstacleAttenuation) * m_pointObstacleBoost; - if (attenuation < 1.0f) - setLight(x, y, lvalue + ScalarLightTraits::subtract(light.value, attenuation)); + if (attenuation < 1.0f) { + auto newLight = ScalarLightTraits::subtract(light.value, attenuation); + if (ScalarLightTraits::maxIntensity(newLight) > 0.0001f) { + if (light.asSpread) + setLight(x, y, lvalue + newLight * 0.25f); + else + setLight(x, y, lvalue + newLight); + } + } } } } @@ -67,8 +79,8 @@ void CellularLightArray::calculatePointLighting(size_t xmin, template <> void CellularLightArray::calculatePointLighting(size_t xmin, size_t ymin, size_t xmax, size_t ymax) { - float perBlockObstacleAttenuation = 1.0f / m_pointMaxObstacle; - float perBlockAirAttenuation = 1.0f / m_pointMaxAir; + float pointPerBlockObstacleAttenuation = 1.0f / m_pointMaxObstacle; + float pointPerBlockAirAttenuation = 1.0f / m_pointMaxAir; for (PointLight light : m_pointLights) { if (light.position[0] < 0 || light.position[0] > m_width - 1 || light.position[1] < 0 || light.position[1] > m_height - 1) @@ -76,8 +88,10 @@ void CellularLightArray::calculatePointLighting(size_t xmin, float maxIntensity = ColoredLightTraits::maxIntensity(light.value); Vec2F beamDirection = Vec2F(1, 0).rotate(light.beamAngle); + float perBlockObstacleAttenuation = light.asSpread ? 1.0f / m_spreadMaxObstacle : pointPerBlockObstacleAttenuation; + float perBlockAirAttenuation = light.asSpread ? 1.0f / m_spreadMaxAir : pointPerBlockAirAttenuation; - float maxRange = maxIntensity * m_pointMaxAir; + float maxRange = maxIntensity * (light.asSpread ? m_spreadMaxAir : m_pointMaxAir); // The min / max considering the radius of the light size_t lxmin = std::floor(std::max(xmin, light.position[0] - maxRange)); size_t lymin = std::floor(std::max(ymin, light.position[1] - maxRange)); @@ -116,12 +130,21 @@ void CellularLightArray::calculatePointLighting(size_t xmin, float circularizedPerBlockObstacleAttenuation = perBlockObstacleAttenuation / max(fabs(direction[0]), fabs(direction[1])); float blockAttenuation = lineAttenuation(blockPos, light.position, circularizedPerBlockObstacleAttenuation, remainingAttenuation); + attenuation += blockAttenuation; // Apply single obstacle boost (determine single obstacle by one // block unit of attenuation). - attenuation += blockAttenuation + min(blockAttenuation, circularizedPerBlockObstacleAttenuation) * m_pointObstacleBoost; + if (!light.asSpread) + attenuation += min(blockAttenuation, circularizedPerBlockObstacleAttenuation) * m_pointObstacleBoost; - if (attenuation < 1.0f) - setLight(x, y, lvalue + ColoredLightTraits::subtract(light.value, attenuation)); + if (attenuation < 1.0f) { + auto newLight = ColoredLightTraits::subtract(light.value, attenuation); + if (ColoredLightTraits::maxIntensity(newLight) > 0.0001f) { + if (light.asSpread) + setLight(x, y, lvalue + newLight * 0.25f); + else + setLight(x, y, lvalue + newLight); + } + } } } } diff --git a/source/base/StarCellularLightArray.hpp b/source/base/StarCellularLightArray.hpp index 225d42b..587ae1f 100644 --- a/source/base/StarCellularLightArray.hpp +++ b/source/base/StarCellularLightArray.hpp @@ -56,6 +56,7 @@ public: float beam; float beamAngle; float beamAmbience; + bool asSpread; }; void setParameters(unsigned spreadPasses, float spreadMaxAir, float spreadMaxObstacle, diff --git a/source/base/StarCellularLighting.cpp b/source/base/StarCellularLighting.cpp index 579f48a..3e5cf9a 100644 --- a/source/base/StarCellularLighting.cpp +++ b/source/base/StarCellularLighting.cpp @@ -109,12 +109,12 @@ void CellularLightingCalculator::addSpreadLight(Vec2F const& position, Vec3F con m_lightArray.left().addSpreadLight({arrayPosition, light}); } -void CellularLightingCalculator::addPointLight(Vec2F const& position, Vec3F const& light, float beam, float beamAngle, float beamAmbience) { +void CellularLightingCalculator::addPointLight(Vec2F const& position, Vec3F const& light, float beam, float beamAngle, float beamAmbience, bool asSpread) { Vec2F arrayPosition = position - Vec2F(m_calculationRegion.min()); if (m_monochrome) - m_lightArray.right().addPointLight({arrayPosition, light.max(), beam, beamAngle, beamAmbience}); + m_lightArray.right().addPointLight({arrayPosition, light.max(), beam, beamAngle, beamAmbience, asSpread}); else - m_lightArray.left().addPointLight({arrayPosition, light, beam, beamAngle, beamAmbience}); + m_lightArray.left().addPointLight({arrayPosition, light, beam, beamAngle, beamAmbience, asSpread}); } void CellularLightingCalculator::calculate(Image& output) { diff --git a/source/base/StarCellularLighting.hpp b/source/base/StarCellularLighting.hpp index 7cb230f..7c29bb8 100644 --- a/source/base/StarCellularLighting.hpp +++ b/source/base/StarCellularLighting.hpp @@ -136,7 +136,7 @@ public: void setCellIndex(size_t cellIndex, Vec3F const& light, bool obstacle); void addSpreadLight(Vec2F const& position, Vec3F const& light); - void addPointLight(Vec2F const& position, Vec3F const& light, float beam, float beamAngle, float beamAmbience); + void addPointLight(Vec2F const& position, Vec3F const& light, float beam, float beamAngle, float beamAmbience, bool asSpread = false); // Finish the calculation, and put the resulting color data in the given // output image. The image will be reset to the size of the region given in diff --git a/source/game/StarItemDrop.cpp b/source/game/StarItemDrop.cpp index f3a74c7..bc3d15f 100644 --- a/source/game/StarItemDrop.cpp +++ b/source/game/StarItemDrop.cpp @@ -320,7 +320,7 @@ void ItemDrop::render(RenderCallback* renderCallback) { void ItemDrop::renderLightSources(RenderCallback* renderCallback) { LightSource light; - light.pointLight = false; + light.type = LightType::Spread; light.color = Vec3F::filled(20.f / 255.f); light.position = position(); renderCallback->addLightSource(std::move(light)); diff --git a/source/game/StarLightSource.cpp b/source/game/StarLightSource.cpp index 65b7429..b20b15c 100644 --- a/source/game/StarLightSource.cpp +++ b/source/game/StarLightSource.cpp @@ -3,6 +3,12 @@ namespace Star { +EnumMap const LightTypeNames{ + {LightType::Spread, "Spread"}, + {LightType::Point, "Point"}, + {LightType::PointAsSpread, "PointAsSpread"} +}; + void LightSource::translate(Vec2F const& pos) { position += pos; } @@ -10,7 +16,7 @@ void LightSource::translate(Vec2F const& pos) { DataStream& operator<<(DataStream& ds, LightSource const& lightSource) { ds.write(lightSource.position); ds.write(lightSource.color); - ds.write(lightSource.pointLight); + ds.write(lightSource.type); ds.write(lightSource.pointBeam); ds.write(lightSource.beamAngle); ds.write(lightSource.beamAmbience); @@ -21,7 +27,7 @@ DataStream& operator<<(DataStream& ds, LightSource const& lightSource) { DataStream& operator>>(DataStream& ds, LightSource& lightSource) { ds.read(lightSource.position); ds.read(lightSource.color); - ds.read(lightSource.pointLight); + ds.read(lightSource.type); ds.read(lightSource.pointBeam); ds.read(lightSource.beamAngle); ds.read(lightSource.beamAmbience); diff --git a/source/game/StarLightSource.hpp b/source/game/StarLightSource.hpp index a6948cb..673cd56 100644 --- a/source/game/StarLightSource.hpp +++ b/source/game/StarLightSource.hpp @@ -2,14 +2,22 @@ #include "StarVector.hpp" #include "StarDataStream.hpp" +#include "StarBiMap.hpp" namespace Star { +enum class LightType : uint8_t { + Spread = 0, + Point = 1, + PointAsSpread = 2 // Point with spread-like range +}; + +extern EnumMap const LightTypeNames; + struct LightSource { Vec2F position; Vec3F color; - - bool pointLight; + LightType type; // pointBeam of 0.0 means light has no beam component, as pointBeam goes up, // the dropoff from the beamAngle becomes faster and faster. float pointBeam; diff --git a/source/game/StarNetworkedAnimator.cpp b/source/game/StarNetworkedAnimator.cpp index d013c48..ccec4fd 100644 --- a/source/game/StarNetworkedAnimator.cpp +++ b/source/game/StarNetworkedAnimator.cpp @@ -717,7 +717,7 @@ List NetworkedAnimator::lightSources(Vec2F const& translate) const lightSources.append(LightSource{ position + translate, color.toRgbF(), - pair.second.pointLight, + pair.second.pointLight ? LightType::Point : LightType::Spread, pair.second.pointBeam, pointAngle, pair.second.beamAmbience diff --git a/source/game/StarObject.cpp b/source/game/StarObject.cpp index 7bac350..dd19268 100644 --- a/source/game/StarObject.cpp +++ b/source/game/StarObject.cpp @@ -262,7 +262,7 @@ List Object::lightSources() const { LightSource lightSource; lightSource.position = position() + centerOfTile(orientation->lightPosition); lightSource.color = color.toRgbF(); - lightSource.pointLight = m_config->pointLight; + lightSource.type = m_config->lightType; lightSource.pointBeam = m_config->pointBeam; lightSource.beamAngle = orientation->beamAngle; lightSource.beamAmbience = m_config->beamAmbience; diff --git a/source/game/StarObjectDatabase.cpp b/source/game/StarObjectDatabase.cpp index 67a3c67..8ed56e4 100644 --- a/source/game/StarObjectDatabase.cpp +++ b/source/game/StarObjectDatabase.cpp @@ -495,7 +495,10 @@ ObjectConfigPtr ObjectDatabase::readConfig(String const& path) { objectConfig->lightColors[pair.first] = jsonToColor(pair.second); } - objectConfig->pointLight = config.getBool("pointLight", false); + if (auto lightType = config.optString("lightType")) + objectConfig->lightType = LightTypeNames.getLeft(*lightType); + else + objectConfig->lightType = (LightType)config.getBool("pointLight", false); objectConfig->pointBeam = config.getFloat("pointBeam", 0.0f); objectConfig->beamAmbience = config.getFloat("beamAmbience", 0.0f); diff --git a/source/game/StarObjectDatabase.hpp b/source/game/StarObjectDatabase.hpp index 76bae0f..ca44c2e 100644 --- a/source/game/StarObjectDatabase.hpp +++ b/source/game/StarObjectDatabase.hpp @@ -131,7 +131,7 @@ struct ObjectConfig { bool interactive; StringMap lightColors; - bool pointLight; + LightType lightType; float pointBeam; float beamAmbience; Maybe> lightFlickering; diff --git a/source/game/StarProjectile.cpp b/source/game/StarProjectile.cpp index 5a73e8b..d00b76b 100644 --- a/source/game/StarProjectile.cpp +++ b/source/game/StarProjectile.cpp @@ -379,7 +379,7 @@ void Projectile::renderLightSources(RenderCallback* renderCallback) { if (renderable.is()) renderCallback->addLightSource(renderable.get()); } - renderCallback->addLightSource({position(), m_config->lightColor.toRgbF(), m_config->pointLight, 0.0f, 0.0f, 0.0f}); + renderCallback->addLightSource({position(), m_config->lightColor.toRgbF(), m_config->lightType, 0.0f, 0.0f, 0.0f}); } Maybe Projectile::receiveMessage(ConnectionId sendingConnection, String const& message, JsonArray const& args) { @@ -825,7 +825,7 @@ void Projectile::processAction(Json const& action) { m_pendingRenderables.append(LightSource{ position(), jsonToColor(parameters.get("color")).toRgbF(), - parameters.getBool("pointLight", true), + (LightType)parameters.getBool("pointLight", true), 0.0f, 0.0f, 0.0f diff --git a/source/game/StarProjectileDatabase.cpp b/source/game/StarProjectileDatabase.cpp index dd7327b..c2a0c26 100644 --- a/source/game/StarProjectileDatabase.cpp +++ b/source/game/StarProjectileDatabase.cpp @@ -118,7 +118,10 @@ ProjectileConfigPtr ProjectileDatabase::readConfig(String const& path) { projectileConfig->lightColor = jsonToColor(config.get("lightColor", JsonArray{0, 0, 0})); projectileConfig->lightPosition = jsonToVec2F(config.get("lightPosition", JsonArray{0, 0})); - projectileConfig->pointLight = config.getBool("pointLight", false); + if (auto lightType = config.optString("lightType")) + projectileConfig->lightType = LightTypeNames.getLeft(*lightType); + else + projectileConfig->lightType = (LightType)config.getBool("pointLight", false); projectileConfig->persistentAudio = config.getString("persistentAudio", ""); diff --git a/source/game/StarProjectileDatabase.hpp b/source/game/StarProjectileDatabase.hpp index 833d0eb..d3cdd3d 100644 --- a/source/game/StarProjectileDatabase.hpp +++ b/source/game/StarProjectileDatabase.hpp @@ -68,7 +68,7 @@ struct ProjectileConfig { Color lightColor; Vec2F lightPosition; - bool pointLight = false; + LightType lightType = LightType::Spread; String persistentAudio; diff --git a/source/game/StarWorldClient.cpp b/source/game/StarWorldClient.cpp index df69b94..535980b 100644 --- a/source/game/StarWorldClient.cpp +++ b/source/game/StarWorldClient.cpp @@ -1652,10 +1652,15 @@ void WorldClient::lightingCalc() { for (auto const& light : lights) { Vec2F position = m_geometry.nearestTo(Vec2F(m_lightingCalculator.calculationRegion().min()), light.position); - if (light.pointLight) - m_lightingCalculator.addPointLight(position, light.color, light.pointBeam, light.beamAngle, light.beamAmbience); - else { + if (light.type == LightType::Spread) m_lightingCalculator.addSpreadLight(position, light.color); + else { + if (light.type == LightType::PointAsSpread) { + // hybrid (used for auto-converted object lights) - 75% spread, 25% point (2nd is applied elsewhere) + m_lightingCalculator.addSpreadLight(position, light.color * 0.75f); + m_lightingCalculator.addPointLight(position, light.color, light.pointBeam, light.beamAngle, light.beamAmbience, true); + } else // fully additive point light + m_lightingCalculator.addPointLight(position, light.color, light.pointBeam, light.beamAngle, light.beamAmbience); } } diff --git a/source/game/StarWorldImpl.hpp b/source/game/StarWorldImpl.hpp index dec827f..3e3728b 100644 --- a/source/game/StarWorldImpl.hpp +++ b/source/game/StarWorldImpl.hpp @@ -445,10 +445,10 @@ namespace WorldImpl { for (auto const& entity : entityMap->entityQuery(RectF(lighting.calculationRegion()))) { for (auto const& light : entity->lightSources()) { Vec2F position = worldGeometry.nearestTo(Vec2F(lighting.calculationRegion().min()), light.position); - if (light.pointLight) - lighting.addPointLight(position, light.color.sum() / 3.0f, light.pointBeam, light.beamAngle, light.beamAmbience); - else + if (light.type == LightType::Spread) lighting.addSpreadLight(position, light.color.sum() / 3.0f); + else + lighting.addPointLight(position, light.color.sum() / 3.0f, light.pointBeam, light.beamAngle, light.beamAmbience); } } diff --git a/source/game/items/StarInspectionTool.cpp b/source/game/items/StarInspectionTool.cpp index a9e3109..cdfe6c2 100644 --- a/source/game/items/StarInspectionTool.cpp +++ b/source/game/items/StarInspectionTool.cpp @@ -54,7 +54,7 @@ List InspectionTool::lightSources() const { float angle = world()->geometry().diff(owner()->aimPosition(), owner()->position()).angle(); LightSource lightSource; - lightSource.pointLight = true; + lightSource.type = LightType::Point; lightSource.position = owner()->position() + owner()->handPosition(hand(), m_lightPosition - m_handPosition); lightSource.color = m_lightColor.toRgbF(); lightSource.pointBeam = m_beamWidth; diff --git a/source/game/items/StarTools.cpp b/source/game/items/StarTools.cpp index 0f2781a..cde44b8 100644 --- a/source/game/items/StarTools.cpp +++ b/source/game/items/StarTools.cpp @@ -239,7 +239,7 @@ List Flashlight::lightSources() const { float angle = world()->geometry().diff(owner()->aimPosition(), owner()->position()).angle(); LightSource lightSource; - lightSource.pointLight = true; + lightSource.type = LightType::Point; lightSource.position = owner()->position() + owner()->handPosition(hand(), (m_lightPosition - m_handPosition) / TilePixels); lightSource.color = m_lightColor.toRgbF(); lightSource.pointBeam = m_beamWidth; diff --git a/source/game/scripting/StarLuaAnimationComponent.hpp b/source/game/scripting/StarLuaAnimationComponent.hpp index 8866724..799c76e 100644 --- a/source/game/scripting/StarLuaAnimationComponent.hpp +++ b/source/game/scripting/StarLuaAnimationComponent.hpp @@ -77,7 +77,7 @@ LuaAnimationComponent::LuaAnimationComponent() { m_lightSources.append({ lightSourceTable.get("position"), lightSourceTable.get("color").toRgbF(), - lightSourceTable.get>("pointLight").value(), + (LightType)lightSourceTable.get>("pointLight").value(), lightSourceTable.get>("pointBeam").value(), lightSourceTable.get>("beamAngle").value(), lightSourceTable.get>("beamAmbience").value()