From 04a964e45f83203a4ee1d8cb706c702206d67017 Mon Sep 17 00:00:00 2001 From: Issac332 <119879937+Issac8658@users.noreply.github.com> Date: Tue, 26 May 2026 17:25:33 +0300 Subject: [PATCH] WM effect and npc names debug --- CMakeLists.txt | 6 ++- binding-mri/sprite-binding.cpp | 36 ++++++++------- scripts/Data_FastTravel.rb | 2 +- scripts/FastTravel.rb | 7 ++- scripts/Game_Switches.rb | 3 ++ scripts/Sprite_Character.rb | 24 +++++++--- shader/worldMachine.frag | 65 +++++++++++++++++++++++++++ shader/worldMachine.vert | 16 +++++++ src/shader.cpp | 19 ++++++++ src/shader.h | 11 +++++ src/sprite.cpp | 82 ++++++++++++++++++++++++---------- src/sprite.h | 50 +++++++++++---------- 12 files changed, 247 insertions(+), 74 deletions(-) create mode 100644 shader/worldMachine.frag create mode 100644 shader/worldMachine.vert diff --git a/CMakeLists.txt b/CMakeLists.txt index 519be8e..41064bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -188,6 +188,7 @@ set(EMBEDDED_INPUT shader/trans.frag shader/hue.frag shader/sprite.frag + shader/worldMachine.frag shader/plane.frag shader/gray.frag shader/bitmapBlit.frag @@ -202,6 +203,7 @@ set(EMBEDDED_INPUT shader/simple.vert shader/simpleColor.vert shader/sprite.vert + shader/worldMachine.vert shader/tilemap.vert shader/blur.frag shader/blurH.vert @@ -321,7 +323,7 @@ find_package(SDL3_image CONFIG) find_package(SDL3_sound CONFIG) find_package(SDL3_ttf CONFIG) find_package(OpenAL CONFIG) -find_package(Boost REQUIRED COMPONENTS program_options) +find_package(Boost REQUIRED COMPONENTS program_options chrono) find_package(PhysFS CONFIG) find_path(PIXMAN_INCLUDE_DIR NAMES pixman.h PATH_SUFFIXES pixman-1) find_library(PIXMAN_LIBRARY NAMES pixman-1 pixman-1_static pixman-1_staticd) @@ -359,7 +361,7 @@ target_link_libraries(${PROJECT_NAME} ${SIGC2_LIBRARIES} ${PLATFORM_LIBRARIES} ${Ruby_LIBRARIES} - Boost::boost ${Boost_LIBRARIES} + Boost::boost Boost::chrono ${Boost_LIBRARIES} ${VORBISFILE_LIBRARIES} ZLIB::ZLIB ${PLATFORM_LIBS} diff --git a/binding-mri/sprite-binding.cpp b/binding-mri/sprite-binding.cpp index d3e0f52..58170c7 100644 --- a/binding-mri/sprite-binding.cpp +++ b/binding-mri/sprite-binding.cpp @@ -71,6 +71,7 @@ DEF_PROP_F(Sprite, WavePhase) DEF_PROP_B(Sprite, Mirror) DEF_PROP_B(Sprite, Obscured) +DEF_PROP_B(Sprite, WorldMachine) RB_METHOD(spriteWidth){ RB_UNUSED_PARAM; @@ -105,23 +106,24 @@ void spriteBindingInit(){ _rb_define_method(klass, "initialize", spriteInitialize); - INIT_PROP_BIND( Sprite, Bitmap, "bitmap" ); - INIT_PROP_BIND( Sprite, SrcRect, "src_rect" ); - INIT_PROP_BIND( Sprite, X, "x" ); - INIT_PROP_BIND( Sprite, Y, "y" ); - INIT_PROP_BIND( Sprite, OX, "ox" ); - INIT_PROP_BIND( Sprite, OY, "oy" ); - INIT_PROP_BIND( Sprite, ZoomX, "zoom_x" ); - INIT_PROP_BIND( Sprite, ZoomY, "zoom_y" ); - INIT_PROP_BIND( Sprite, Angle, "angle" ); - INIT_PROP_BIND( Sprite, Mirror, "mirror" ); - INIT_PROP_BIND( Sprite, BushDepth, "bush_depth" ); - INIT_PROP_BIND( Sprite, Opacity, "opacity" ); - INIT_PROP_BIND( Sprite, BlendType, "blend_type" ); - INIT_PROP_BIND( Sprite, Color, "color" ); - INIT_PROP_BIND( Sprite, Tone, "tone" ); - INIT_PROP_BIND( Sprite, Modulate, "modulate" ); - INIT_PROP_BIND( Sprite, Obscured, "obscured" ); + INIT_PROP_BIND( Sprite, Bitmap, "bitmap" ); + INIT_PROP_BIND( Sprite, SrcRect, "src_rect" ); + INIT_PROP_BIND( Sprite, X, "x" ); + INIT_PROP_BIND( Sprite, Y, "y" ); + INIT_PROP_BIND( Sprite, OX, "ox" ); + INIT_PROP_BIND( Sprite, OY, "oy" ); + INIT_PROP_BIND( Sprite, ZoomX, "zoom_x" ); + INIT_PROP_BIND( Sprite, ZoomY, "zoom_y" ); + INIT_PROP_BIND( Sprite, Angle, "angle" ); + INIT_PROP_BIND( Sprite, Mirror, "mirror" ); + INIT_PROP_BIND( Sprite, BushDepth, "bush_depth" ); + INIT_PROP_BIND( Sprite, Opacity, "opacity" ); + INIT_PROP_BIND( Sprite, BlendType, "blend_type" ); + INIT_PROP_BIND( Sprite, Color, "color" ); + INIT_PROP_BIND( Sprite, Tone, "tone" ); + INIT_PROP_BIND( Sprite, Modulate, "modulate" ); + INIT_PROP_BIND( Sprite, Obscured, "obscured" ); + INIT_PROP_BIND( Sprite, WorldMachine, "world_machine" ); _rb_define_method(klass, "width", spriteWidth); _rb_define_method(klass, "height", spriteHeight); diff --git a/scripts/Data_FastTravel.rb b/scripts/Data_FastTravel.rb index cbe2072..aa91e99 100644 --- a/scripts/Data_FastTravel.rb +++ b/scripts/Data_FastTravel.rb @@ -76,7 +76,7 @@ class FastTravel :mineshaft => ZoneLocations.new(88, -3, 5, 0, nil, nil, nil, :quarry), :factory => ZoneLocations.new(15, -42, 13, 2, nil, nil, :cliffs, :dorms), :dorms => ZoneLocations.new(-46, -49, 20, 4, nil, :factory, nil, :swamp), - :swamp => ZoneLocations.new(-98, -44, 10, 7, nil, :dorms, :docks, nil), + :swamp => ZoneLocations.new(-98, -45, 10, 7, nil, :dorms, :docks, nil), :docks => ZoneLocations.new(-82, -9, -4, -2, :swamp, nil, :entrance, nil), :quarry => ZoneLocations.new(52, -4, 17, -3, nil, :mineshaft, nil, :cliffs), }), diff --git a/scripts/FastTravel.rb b/scripts/FastTravel.rb index d050ad7..cd01b10 100644 --- a/scripts/FastTravel.rb +++ b/scripts/FastTravel.rb @@ -37,6 +37,7 @@ class FastTravel @niko_icon.zoom_x = @niko_icon.zoom_y = @scale_multiplier @niko_icon.z = 10 @niko_icon.opacity = 0 + @niko_icon.world_machine = true @niko_pos_x = 0.0 @niko_pos_y = 0.0 @@ -68,6 +69,9 @@ class FastTravel @arrow_top.opacity = @arrow_bottom.opacity = @arrow_left.opacity = @arrow_right.opacity = 0 + + @arrow_top.world_machine = @arrow_bottom.world_machine = + @arrow_left.world_machine = @arrow_right.world_machine = true @arrow_top.z = @arrow_bottom.z = @arrow_left.z = @arrow_right.z = 11 @@ -191,6 +195,7 @@ class FastTravel spr.x = Graphics.width / 2 + zone.locations[item].x * @scale_multiplier spr.y = Graphics.height / 2 + zone.locations[item].y * @scale_multiplier spr.opacity = 0 + spr.world_machine = true @data_locations[item] = spr set_color(item) else @@ -224,8 +229,8 @@ class FastTravel def update zone = ZONES[$game_fasttravel.zone] - zone = zone == nil ? Zone.new("", {}, {}) : zone + if zone.locations != nil && !@legacy_ui @arrows_timer += 1 if @arrows_timer >= 30 diff --git a/scripts/Game_Switches.rb b/scripts/Game_Switches.rb index e5fbe6b..8487c31 100644 --- a/scripts/Game_Switches.rb +++ b/scripts/Game_Switches.rb @@ -43,3 +43,6 @@ class Game_Switches end end end + +# some switches that we know of +# 160 - re-playing game (when Niko is TWM) \ No newline at end of file diff --git a/scripts/Sprite_Character.rb b/scripts/Sprite_Character.rb index df1e729..b4633c3 100644 --- a/scripts/Sprite_Character.rb +++ b/scripts/Sprite_Character.rb @@ -22,6 +22,9 @@ class Sprite_Character @sprite = RPG::Sprite.new(viewport) @light_sprite = RPG::Sprite.new(light_viewport) @light_sprite.blend_type = 1 + @text_sprite = Sprite.new(viewport) + @text_sprite.bitmap = Bitmap.new(Graphics.width, 30) + @text_sprite.bitmap.font.size = 12 @character = character update end @@ -31,6 +34,15 @@ class Sprite_Character def update # Choose the appropriate light sprite @light_sprite.viewport = ($game_screen.tone.blank?) ? @viewport : @light_viewport + @light_sprite.world_machine = @sprite.world_machine = @character.character_name.start_with?("en") || (@character.character_name.start_with?("niko") && $game_switches[160]) + if Window_Settings.DebugIsEnabled == true + @text_sprite.bitmap.draw_text(0, 0, 256, 30, @character.character_name) + @text_sprite.x = @character.screen_x + @text_sprite.y = @character.screen_y + @text_sprite.z = @character.screen_z + 2 + else + @text_sprite.bitmap.clear + end # Update sprites @sprite.update @light_sprite.update @@ -53,15 +65,15 @@ class Sprite_Character self.oy = 32 # If tile ID value is invalid else - name = @character.character_name - translation_name = "#{$persistent.langcode}/#{name}" + name = @character.character_name + translation_name = "#{$persistent.langcode}/#{name}" if File.exist?("Graphics/Characters/#{translation_name}.png") @sprite.bitmap = RPG::Cache.character(translation_name, - @character.character_hue) - else + @character.character_hue) + else @sprite.bitmap = RPG::Cache.character(name, - @character.character_hue) - end + @character.character_hue) + end begin @light_sprite.bitmap = RPG::Cache.lightmap(@character.character_name) diff --git a/shader/worldMachine.frag b/shader/worldMachine.frag new file mode 100644 index 0000000..3ba77d4 --- /dev/null +++ b/shader/worldMachine.frag @@ -0,0 +1,65 @@ +uniform sampler2D texture; +uniform vec2 texSizeInv; + +uniform lowp vec4 tone; + +uniform lowp float opacity; +uniform lowp vec4 color; +uniform lowp vec4 modulate; + +uniform float bushDepth; +uniform lowp float bushOpacity; + +uniform float uTime; + +varying vec2 v_texCoord; + +const vec3 lumaF = vec3(.299, .587, .114); + +vec2 rand(float seed) { + return fract(sin(vec2(seed * 12.9898, seed * 78.233)) * 43758.5453); +} + +vec4 clampedTexture2D(sampler2D s, vec2 uv){ + if (uv.x > 1.0 || uv.y > 1.0 || uv.x < 0.0 || uv.y < 0.0) + return vec4(0, 0, 0, 0); + else + return texture2D(s, uv); +} + +void main(){ + + /* Sample source color */ + vec4 frag = texture2D(texture, v_texCoord); + + /* Apply gray */ + float luma = dot(frag.rgb, lumaF); + frag.rgb = mix(frag.rgb, vec3(luma), tone.w); + + /* Apply tone */ + frag.rgb += tone.rgb; + + /* Apply color */ + frag.rgb = mix(frag.rgb, color.rgb, color.a); + + /* Apply modulation */ + frag *= modulate; + + /* glitch effect */ + float randTime = rand(floor(uTime * 15.0)); + vec4 glitchFrag1 = clampedTexture2D(texture, v_texCoord + floor(randTime * 2.0 - 0.5) * texSizeInv); + vec4 glitchFrag2 = clampedTexture2D(texture, v_texCoord + floor(rand(floor(uTime * 15.0 + 67.6767)) * 2.0 - 0.5) * texSizeInv); + vec4 glitchFrag3 = clampedTexture2D(texture, v_texCoord + floor(rand(floor(uTime * 15.0 + 42.5252)) * 2.0 - 0.5) * texSizeInv); + vec3 glitchFrag = vec3(glitchFrag1.r, glitchFrag2.g * floor(randTime + 0.5), glitchFrag3.b * floor(1.0 - randTime + 0.5)); + frag.rgb += mix(glitchFrag, glitchFrag * 0.25, frag.a); + frag.a += (glitchFrag1.a + glitchFrag2.a + glitchFrag3.a) * 0.125; + + /* Apply opacity */ + frag.a *= opacity; + + /* Apply bush alpha by mathematical if */ + lowp float underBush = float(v_texCoord.y < bushDepth); + frag.a *= clamp(bushOpacity + underBush, 0.0, 1.0); + + gl_FragColor = frag; +} diff --git a/shader/worldMachine.vert b/shader/worldMachine.vert new file mode 100644 index 0000000..fca7939 --- /dev/null +++ b/shader/worldMachine.vert @@ -0,0 +1,16 @@ + +uniform mat4 projMat; + +uniform mat4 spriteMat; + +uniform vec2 texSizeInv; + +attribute vec2 position; +attribute vec2 texCoord; + +varying vec2 v_texCoord; + +void main(){ + gl_Position = projMat * spriteMat * vec4(position, 0, 1); + v_texCoord = texCoord * texSizeInv; +} diff --git a/src/shader.cpp b/src/shader.cpp index 06f562a..d104656 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -30,6 +30,7 @@ #include "common.h.xxd" #include "sprite.frag.xxd" +#include "worldMachine.frag.xxd" #include "hue.frag.xxd" #include "trans.frag.xxd" #include "transSimple.frag.xxd" @@ -46,6 +47,7 @@ #include "simple.vert.xxd" #include "simpleColor.vert.xxd" #include "sprite.vert.xxd" +#include "worldMachine.vert.xxd" #include "tilemap.vert.xxd" #include "blur.frag.xxd" #include "simpleMatrix.vert.xxd" @@ -409,6 +411,23 @@ void SpriteShader::setBushOpacity(float value){ } +WMShader::WMShader(){ + INIT_SHADER(worldMachine, worldMachine, WMShader); + SpriteShader::init(); + + GET_U(uTime); + //GET_U(resolution); +} + +void WMShader::setTime(float value){ + gl.Uniform1f(u_uTime, value); +} +/* +void WMShader::setResolution(float x, float y){ + gl.Uniform2f(u_resolution, x, y); +}*/ + + PlaneShader::PlaneShader(){ INIT_SHADER(simple, plane, PlaneShader); diff --git a/src/shader.h b/src/shader.h index 220f42d..7cd1c4d 100644 --- a/src/shader.h +++ b/src/shader.h @@ -176,6 +176,16 @@ private: GLint u_spriteMat, u_tone, u_opacity, u_color, u_modulate, u_bushDepth, u_bushOpacity; }; +class WMShader : public SpriteShader{ +public: + WMShader(); + + void setTime(float value); + //void setResolution(float x, float y); +private: + GLint u_uTime/*, u_resolution*/; +}; + class PlaneShader : public ShaderBase{ public: PlaneShader(); @@ -300,6 +310,7 @@ struct ShaderSet{ SimpleSpriteShader simpleSprite; AlphaSpriteShader alphaSprite; SpriteShader sprite; + WMShader worldMachine; PlaneShader plane; GrayShader gray; TilemapShader tilemap; diff --git a/src/sprite.cpp b/src/sprite.cpp index 63ed31c..9935941 100644 --- a/src/sprite.cpp +++ b/src/sprite.cpp @@ -41,8 +41,11 @@ #include #include +#include struct SpritePrivate{ + boost::chrono::high_resolution_clock::time_point startTime = boost::chrono::high_resolution_clock::now(); + Bitmap *bitmap; Quad quad; @@ -66,6 +69,7 @@ struct SpritePrivate{ bool isVisible; bool obscured; + bool worldMachine; Color *color; Tone *tone; @@ -99,6 +103,7 @@ struct SpritePrivate{ blendType(BlendNormal), isVisible(false), obscured(false), + worldMachine(false), color(&tmp.color), tone(&tmp.tone), modulate(&tmp.modulate) @@ -292,31 +297,32 @@ Sprite::~Sprite(){ dispose(); } -DEF_ATTR_RD_SIMPLE(Sprite, Bitmap, Bitmap*, p->bitmap) -DEF_ATTR_RD_SIMPLE(Sprite, X, int, p->trans.getPosition().x) -DEF_ATTR_RD_SIMPLE(Sprite, Y, int, p->trans.getPosition().y) -DEF_ATTR_RD_SIMPLE(Sprite, OX, int, p->trans.getOrigin().x) -DEF_ATTR_RD_SIMPLE(Sprite, OY, int, p->trans.getOrigin().y) -DEF_ATTR_RD_SIMPLE(Sprite, ZoomX, float, p->trans.getScale().x) -DEF_ATTR_RD_SIMPLE(Sprite, ZoomY, float, p->trans.getScale().y) -DEF_ATTR_RD_SIMPLE(Sprite, Angle, float, p->trans.getRotation()) -DEF_ATTR_RD_SIMPLE(Sprite, Mirror, bool, p->mirrored) -DEF_ATTR_RD_SIMPLE(Sprite, BushDepth, int, p->bushDepth) -DEF_ATTR_RD_SIMPLE(Sprite, BlendType, int, p->blendType) -DEF_ATTR_RD_SIMPLE(Sprite, Width, int, p->srcRect->width) -DEF_ATTR_RD_SIMPLE(Sprite, Height, int, p->srcRect->height) -DEF_ATTR_RD_SIMPLE(Sprite, WaveAmp, int, p->wave.amp) -DEF_ATTR_RD_SIMPLE(Sprite, WaveLength, int, p->wave.length) -DEF_ATTR_RD_SIMPLE(Sprite, WaveSpeed, int, p->wave.speed) -DEF_ATTR_RD_SIMPLE(Sprite, WavePhase, float, p->wave.phase) +DEF_ATTR_RD_SIMPLE(Sprite, Bitmap, Bitmap*, p->bitmap) +DEF_ATTR_RD_SIMPLE(Sprite, X, int, p->trans.getPosition().x) +DEF_ATTR_RD_SIMPLE(Sprite, Y, int, p->trans.getPosition().y) +DEF_ATTR_RD_SIMPLE(Sprite, OX, int, p->trans.getOrigin().x) +DEF_ATTR_RD_SIMPLE(Sprite, OY, int, p->trans.getOrigin().y) +DEF_ATTR_RD_SIMPLE(Sprite, ZoomX, float, p->trans.getScale().x) +DEF_ATTR_RD_SIMPLE(Sprite, ZoomY, float, p->trans.getScale().y) +DEF_ATTR_RD_SIMPLE(Sprite, Angle, float, p->trans.getRotation()) +DEF_ATTR_RD_SIMPLE(Sprite, Mirror, bool, p->mirrored) +DEF_ATTR_RD_SIMPLE(Sprite, BushDepth, int, p->bushDepth) +DEF_ATTR_RD_SIMPLE(Sprite, BlendType, int, p->blendType) +DEF_ATTR_RD_SIMPLE(Sprite, Width, int, p->srcRect->width) +DEF_ATTR_RD_SIMPLE(Sprite, Height, int, p->srcRect->height) +DEF_ATTR_RD_SIMPLE(Sprite, WaveAmp, int, p->wave.amp) +DEF_ATTR_RD_SIMPLE(Sprite, WaveLength, int, p->wave.length) +DEF_ATTR_RD_SIMPLE(Sprite, WaveSpeed, int, p->wave.speed) +DEF_ATTR_RD_SIMPLE(Sprite, WavePhase, float, p->wave.phase) -DEF_ATTR_SIMPLE(Sprite, BushOpacity, int, p->bushOpacity) -DEF_ATTR_SIMPLE(Sprite, Opacity, int, p->opacity) -DEF_ATTR_SIMPLE(Sprite, SrcRect, Rect&, *p->srcRect) -DEF_ATTR_SIMPLE(Sprite, Color, Color&, *p->color) -DEF_ATTR_SIMPLE(Sprite, Tone, Tone&, *p->tone) -DEF_ATTR_SIMPLE(Sprite, Modulate, Color&, *p->modulate) -DEF_ATTR_SIMPLE(Sprite, Obscured, bool, p->obscured) +DEF_ATTR_SIMPLE(Sprite, BushOpacity, int, p->bushOpacity) +DEF_ATTR_SIMPLE(Sprite, Opacity, int, p->opacity) +DEF_ATTR_SIMPLE(Sprite, SrcRect, Rect&, *p->srcRect) +DEF_ATTR_SIMPLE(Sprite, Color, Color&, *p->color) +DEF_ATTR_SIMPLE(Sprite, Tone, Tone&, *p->tone) +DEF_ATTR_SIMPLE(Sprite, Modulate, Color&, *p->modulate) +DEF_ATTR_SIMPLE(Sprite, Obscured, bool, p->obscured) +DEF_ATTR_SIMPLE(Sprite, WorldMachine, bool, p->worldMachine) void Sprite::setBitmap(Bitmap *bitmap){ guardDisposed(); @@ -506,6 +512,34 @@ void Sprite::draw(){ shader.setObscured(shState->graphics().obscuredTex()); base = &shader; } + else if (p->worldMachine){ + WMShader &shader = shState->shaders().worldMachine; + + shader.bind(); + shader.applyViewportProj(); + shader.setSpriteMat(p->trans.getMatrix()); + + shader.setTone(p->tone->norm); + shader.setOpacity(p->opacity.norm); + shader.setBushDepth(p->efBushDepth); + shader.setBushOpacity(p->bushOpacity.norm); + + /* When both flashing and effective color are set, + * the one with higher alpha will be blended */ + const Vec4 *blend = (flashing && flashColor.w > p->color->norm.w) ? + &flashColor : &p->color->norm; + + shader.setColor(*blend); + shader.setModulate(p->modulate->norm); + //shader.setResolution(p->bitmap->width(), p->bitmap->height()); + + boost::chrono::high_resolution_clock::time_point currentTime = boost::chrono::high_resolution_clock::now(); + + boost::chrono::duration elapsed = currentTime - p->startTime; + shader.setTime(elapsed.count()); + + base = &shader; + } else if (renderEffect){ SpriteShader &shader = shState->shaders().sprite; diff --git a/src/sprite.h b/src/sprite.h index 3429372..b9db4a5 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -28,6 +28,8 @@ #include "viewport.h" #include "util.h" +#include + class Bitmap; struct Color; struct Tone; @@ -44,29 +46,31 @@ public: int getHeight() const; void update(); - - DECL_ATTR( Bitmap, Bitmap* ) - DECL_ATTR( SrcRect, Rect& ) - DECL_ATTR( X, int ) - DECL_ATTR( Y, int ) - DECL_ATTR( OX, int ) - DECL_ATTR( OY, int ) - DECL_ATTR( ZoomX, float ) - DECL_ATTR( ZoomY, float ) - DECL_ATTR( Angle, float ) - DECL_ATTR( Mirror, bool ) - DECL_ATTR( BushDepth, int ) - DECL_ATTR( BushOpacity, int ) - DECL_ATTR( Opacity, int ) - DECL_ATTR( BlendType, int ) - DECL_ATTR( Color, Color& ) - DECL_ATTR( Modulate, Color& ) - DECL_ATTR( Tone, Tone& ) - DECL_ATTR( WaveAmp, int ) - DECL_ATTR( WaveLength, int ) - DECL_ATTR( WaveSpeed, int ) - DECL_ATTR( WavePhase, float ) - DECL_ATTR( Obscured, bool ) + + DECL_ATTR( Bitmap, Bitmap* ) + DECL_ATTR( SrcRect, Rect& ) + DECL_ATTR( X, int ) + DECL_ATTR( Y, int ) + DECL_ATTR( OX, int ) + DECL_ATTR( OY, int ) + DECL_ATTR( ZoomX, float ) + DECL_ATTR( ZoomY, float ) + DECL_ATTR( Angle, float ) + DECL_ATTR( Mirror, bool ) + DECL_ATTR( BushDepth, int ) + DECL_ATTR( BushOpacity, int ) + DECL_ATTR( Opacity, int ) + DECL_ATTR( BlendType, int ) + DECL_ATTR( Color, Color& ) + DECL_ATTR( Modulate, Color& ) + DECL_ATTR( Tone, Tone& ) + DECL_ATTR( WaveAmp, int ) + DECL_ATTR( WaveLength, int ) + DECL_ATTR( WaveSpeed, int ) + DECL_ATTR( WavePhase, float ) + DECL_ATTR( Obscured, bool ) + DECL_ATTR( WorldMachine, bool ) + DECL_ATTR( startTime, boost::chrono::high_resolution_clock::time_point) void initDynAttribs();