-
Notifications
You must be signed in to change notification settings - Fork 14
feat(lighting): support for OTClient style light rendering #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
cab5904
5467baa
a230e91
9a4d5df
b680d56
181dfbf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,19 +1,31 @@ | ||
| #pragma once | ||
|
|
||
| #include "Core/Config.h" | ||
|
|
||
| #include <cstdint> | ||
|
|
||
| namespace MapEditor { | ||
| namespace Domain { | ||
|
|
||
| /** | ||
| * Global world light (mimics server WorldLight protocol message). | ||
| * Defines the ambient light level for above-ground floors. | ||
| */ | ||
| struct GlobalLight { | ||
| uint8_t intensity = 0; // Server ambient level (0-255) | ||
| uint8_t color = Config::Lighting::DEFAULT_SERVER_LIGHT_COLOR; | ||
| }; | ||
|
|
||
| /** | ||
| * A light source extracted from a tile item. | ||
| * Contains position, color (8-bit palette index), and intensity. | ||
| */ | ||
| struct LightSource { | ||
| int32_t x = 0; // Tile X position | ||
| int32_t y = 0; // Tile Y position | ||
| uint8_t color = 215; // 8-bit palette index (default: white-ish) | ||
| uint8_t color = Config::Lighting::DEFAULT_SERVER_LIGHT_COLOR; | ||
| uint8_t intensity = 0; // 0-255 (affects light radius) | ||
| int16_t source_floor = 0; // Floor this light originates from (for blocking) | ||
| }; | ||
|
|
||
| /** | ||
|
|
@@ -22,8 +34,23 @@ struct LightSource { | |
| */ | ||
| struct LightConfig { | ||
| bool enabled = false; // Master enable for this viewport | ||
| uint8_t ambient_level = 255; // 0 = complete darkness, 255 = full bright | ||
| uint8_t ambient_color = 215; // 8-bit palette index for ambient | ||
| GlobalLight global_light; // Server global light (above-ground ambient) | ||
| uint8_t client_slider = Config::Lighting::DEFAULT_MINIMUM_AMBIENT; | ||
| int16_t camera_floor = Config::Map::GROUND_LAYER; | ||
| // Deprecated compatibility fields. Rendering computes final ambient from | ||
| // global_light, client_slider, and camera_floor elsewhere. | ||
| uint8_t ambient_color = Config::Lighting::DEFAULT_SERVER_LIGHT_COLOR; | ||
| uint8_t ambient_level = 255; | ||
|
|
||
| /** | ||
| * Hash fields that affect generated lighting. | ||
| */ | ||
| [[nodiscard]] uint32_t computeHash() const { | ||
| return static_cast<uint32_t>(global_light.intensity) | | ||
| (static_cast<uint32_t>(global_light.color) << 8) | | ||
| (static_cast<uint32_t>(client_slider) << 16) | | ||
| (static_cast<uint32_t>(camera_floor & 0xFF) << 24); | ||
| } | ||
| }; | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟢 The comment says |
||
| } // namespace Domain | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -135,6 +135,25 @@ CreatureXmlReader::parseCreatureNode(const pugi::xml_node &node, bool isNpc, | |
| creature->outfit.lookMountFeet = static_cast<uint16_t>(attr.as_uint()); | ||
| } | ||
|
|
||
| // Light properties (optional) | ||
| const auto read_light_u8 = [&](const char *attribute_name) -> uint8_t { | ||
| const auto attr = node.attribute(attribute_name); | ||
| if (!attr) return 0; | ||
|
|
||
| const unsigned int raw_value = attr.as_uint(); | ||
| if (raw_value > 255U) { | ||
| warnings.push_back(std::string("Creature '") + creature->name + | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟠 Using |
||
| "' has " + attribute_name + "=" + | ||
| std::to_string(raw_value) + "; clamped to 255"); | ||
| return 255; | ||
| } | ||
|
|
||
| return static_cast<uint8_t>(raw_value); | ||
| }; | ||
|
|
||
| creature->light_level = read_light_u8("lightlevel"); | ||
| creature->light_color = read_light_u8("lightcolor"); | ||
|
|
||
| return creature; | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 The
computeHashfunction currently excludes theenabledfield. WhileLightingPasschecks this field before calling render, it might be safer to include it in the hash to ensure the cache is invalidated if the master toggle is changed, or add a comment explaining why it's omitted.