From 81068f820d12aeacc843be02af964d4697bc48d9 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Wed, 28 Nov 2012 23:47:26 -0200 Subject: [PATCH] Implement lights, thanks @Tarjei400 Now otclient have lights! This code was originally made by @Tarjei400, I have improved it and merged into otclient master. Many thanks for tarjei for the contribution. Warning, this still experimental, fixes may come in the next days. --- modules/client/client.otmod | 3 +- modules/game_interface/widgets/uigamemap.lua | 1 + src/framework/graphics/painter.cpp | 3 + src/framework/graphics/painter.h | 3 +- src/otclient/CMakeLists.txt | 2 + src/otclient/creature.cpp | 14 ++- src/otclient/creature.h | 5 +- src/otclient/declarations.h | 2 + src/otclient/effect.cpp | 4 +- src/otclient/effect.h | 2 +- src/otclient/item.cpp | 4 +- src/otclient/item.h | 2 +- src/otclient/lightview.cpp | 122 +++++++++++++++++++ src/otclient/lightview.h | 63 ++++++++++ src/otclient/luafunctions.cpp | 2 + src/otclient/mapview.cpp | 31 ++++- src/otclient/mapview.h | 5 + src/otclient/missile.cpp | 4 +- src/otclient/missile.h | 2 +- src/otclient/thing.h | 2 +- src/otclient/thingtype.cpp | 9 +- src/otclient/thingtype.h | 2 +- src/otclient/tile.cpp | 27 ++-- src/otclient/tile.h | 3 +- src/otclient/uimap.cpp | 2 + src/otclient/uimap.h | 2 + 26 files changed, 283 insertions(+), 38 deletions(-) create mode 100644 src/otclient/lightview.cpp create mode 100644 src/otclient/lightview.h diff --git a/modules/client/client.otmod b/modules/client/client.otmod index 73f6b025..6bbde146 100644 --- a/modules/client/client.otmod +++ b/modules/client/client.otmod @@ -11,12 +11,11 @@ Module //- client_particles - client_topmenu - client_background - //- client_about - client_options - client_terminal - client_modulemanager - client_entergame - - client_stats + //- client_stats @onLoad: | dofile 'client' diff --git a/modules/game_interface/widgets/uigamemap.lua b/modules/game_interface/widgets/uigamemap.lua index 51ebeecf..8072ff61 100644 --- a/modules/game_interface/widgets/uigamemap.lua +++ b/modules/game_interface/widgets/uigamemap.lua @@ -4,6 +4,7 @@ function UIGameMap.create() local gameMap = UIGameMap.internalCreate() gameMap:setKeepAspectRatio(true) gameMap:setVisibleDimension({width = 15, height = 11}) + gameMap:setDrawLights(true) return gameMap end diff --git a/src/framework/graphics/painter.cpp b/src/framework/graphics/painter.cpp index a41b6dba..c417c128 100644 --- a/src/framework/graphics/painter.cpp +++ b/src/framework/graphics/painter.cpp @@ -210,6 +210,9 @@ void Painter::updateGlCompositionMode() case CompositionMode_DestBlending: glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA); break; + case CompositionMode_Light: + glBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR); + break; } } diff --git a/src/framework/graphics/painter.h b/src/framework/graphics/painter.h index e3ff81ad..103ca6f3 100644 --- a/src/framework/graphics/painter.h +++ b/src/framework/graphics/painter.h @@ -36,7 +36,8 @@ public: CompositionMode_Multiply, CompositionMode_Add, CompositionMode_Replace, - CompositionMode_DestBlending + CompositionMode_DestBlending, + CompositionMode_Light }; enum DrawMode { Triangles = GL_TRIANGLES, diff --git a/src/otclient/CMakeLists.txt b/src/otclient/CMakeLists.txt index 713e9524..86c91ffe 100644 --- a/src/otclient/CMakeLists.txt +++ b/src/otclient/CMakeLists.txt @@ -44,6 +44,8 @@ set(otclient_SOURCES ${otclient_SOURCES} ${CMAKE_CURRENT_LIST_DIR}/mapio.cpp ${CMAKE_CURRENT_LIST_DIR}/mapview.cpp ${CMAKE_CURRENT_LIST_DIR}/mapview.h + ${CMAKE_CURRENT_LIST_DIR}/lightview.cpp + ${CMAKE_CURRENT_LIST_DIR}/lightview.h ${CMAKE_CURRENT_LIST_DIR}/missile.cpp ${CMAKE_CURRENT_LIST_DIR}/missile.h ${CMAKE_CURRENT_LIST_DIR}/outfit.cpp diff --git a/src/otclient/creature.cpp b/src/otclient/creature.cpp index b4a1c90b..a13bdf38 100644 --- a/src/otclient/creature.cpp +++ b/src/otclient/creature.cpp @@ -29,6 +29,7 @@ #include "game.h" #include "effect.h" #include "luavaluecasts.h" +#include "lightview.h" #include #include @@ -58,7 +59,7 @@ Creature::Creature() : Thing() m_footStep = 0; } -void Creature::draw(const Point& dest, float scaleFactor, bool animate) +void Creature::draw(const Point& dest, float scaleFactor, bool animate, LightView *lightView) { if(!canBeSeen()) return; @@ -79,9 +80,12 @@ void Creature::draw(const Point& dest, float scaleFactor, bool animate) internalDrawOutfit(dest + animationOffset * scaleFactor, scaleFactor, animate, animate, m_direction); m_footStepDrawn = true; + + if(lightView && m_light.intensity > 0) + lightView->addLightSource(dest + (animationOffset + Point(16,16)) * scaleFactor, scaleFactor, m_light); } -void Creature::internalDrawOutfit(Point dest, float scaleFactor, bool animateWalk, bool animateIdle, Otc::Direction direction) +void Creature::internalDrawOutfit(Point dest, float scaleFactor, bool animateWalk, bool animateIdle, Otc::Direction direction, LightView *lightView) { // outfit is a real creature if(m_outfit.getCategory() == ThingCategoryCreature) { @@ -105,7 +109,7 @@ void Creature::internalDrawOutfit(Point dest, float scaleFactor, bool animateWal if(m_outfit.getMount() != 0) { auto datType = g_things.rawGetThingType(m_outfit.getMount(), ThingCategoryCreature); dest -= datType->getDisplacement() * scaleFactor; - datType->draw(dest, scaleFactor, 0, xPattern, 0, 0, animationPhase); + datType->draw(dest, scaleFactor, 0, xPattern, 0, 0, animationPhase, lightView); dest += getDisplacement() * scaleFactor; zPattern = 1; } @@ -118,7 +122,7 @@ void Creature::internalDrawOutfit(Point dest, float scaleFactor, bool animateWal continue; auto datType = rawGetThingType(); - datType->draw(dest, scaleFactor, 0, xPattern, yPattern, zPattern, animationPhase); + datType->draw(dest, scaleFactor, 0, xPattern, yPattern, zPattern, animationPhase, yPattern == 0 ? lightView : nullptr); if(getLayers() > 1) { Color oldColor = g_painter->getColor(); @@ -161,7 +165,7 @@ void Creature::internalDrawOutfit(Point dest, float scaleFactor, bool animateWal if(m_outfit.getCategory() == ThingCategoryEffect) animationPhase = std::min(animationPhase+1, animationPhases); - type->draw(dest - (getDisplacement() * scaleFactor), scaleFactor, 0, 0, 0, 0, animationPhase); + type->draw(dest - (getDisplacement() * scaleFactor), scaleFactor, 0, 0, 0, 0, animationPhase, lightView); } } diff --git a/src/otclient/creature.h b/src/otclient/creature.h index a7809a25..97de4436 100644 --- a/src/otclient/creature.h +++ b/src/otclient/creature.h @@ -26,6 +26,7 @@ #include "thing.h" #include "outfit.h" #include "tile.h" +#include "mapview.h" #include #include #include @@ -44,9 +45,9 @@ public: Creature(); - virtual void draw(const Point& dest, float scaleFactor, bool animate); + virtual void draw(const Point& dest, float scaleFactor, bool animate, LightView *lightView = nullptr); - void internalDrawOutfit(Point dest, float scaleFactor, bool animateWalk, bool animateIdle, Otc::Direction direction); + void internalDrawOutfit(Point dest, float scaleFactor, bool animateWalk, bool animateIdle, Otc::Direction direction, LightView *lightView = nullptr); void drawOutfit(const Rect& destRect, bool resize); void drawInformation(const Point& point, bool useGray, const Rect& parentRect); diff --git a/src/otclient/declarations.h b/src/otclient/declarations.h index 698182ed..19758dcf 100644 --- a/src/otclient/declarations.h +++ b/src/otclient/declarations.h @@ -31,6 +31,7 @@ class Map; class Game; class MapView; +class LightView; class Tile; class Thing; class Item; @@ -52,6 +53,7 @@ class CreatureType; class Spawn; typedef stdext::shared_object_ptr MapViewPtr; +typedef stdext::shared_object_ptr LightViewPtr; typedef stdext::shared_object_ptr TilePtr; typedef stdext::shared_object_ptr ThingPtr; typedef stdext::shared_object_ptr ItemPtr; diff --git a/src/otclient/effect.cpp b/src/otclient/effect.cpp index b64cdfc2..48999f14 100644 --- a/src/otclient/effect.cpp +++ b/src/otclient/effect.cpp @@ -24,7 +24,7 @@ #include "map.h" #include -void Effect::draw(const Point& dest, float scaleFactor, bool animate) +void Effect::draw(const Point& dest, float scaleFactor, bool animate, LightView *lightView) { if(m_id == 0) return; @@ -32,7 +32,7 @@ void Effect::draw(const Point& dest, float scaleFactor, bool animate) int animationPhase = 0; if(animate) animationPhase = std::min((int)(m_animationTimer.ticksElapsed() / m_phaseDuration), getAnimationPhases() - 1); - rawGetThingType()->draw(dest, scaleFactor, 0, 0, 0, 0, animationPhase); + rawGetThingType()->draw(dest, scaleFactor, 0, 0, 0, 0, animationPhase, lightView); } void Effect::onAppear() diff --git a/src/otclient/effect.h b/src/otclient/effect.h index 97a95a36..934c5f94 100644 --- a/src/otclient/effect.h +++ b/src/otclient/effect.h @@ -35,7 +35,7 @@ class Effect : public Thing }; public: - void draw(const Point& dest, float scaleFactor, bool animate); + void draw(const Point& dest, float scaleFactor, bool animate, LightView *lightView = nullptr); void setId(uint32 id); uint32 getId() { return m_id; } diff --git a/src/otclient/item.cpp b/src/otclient/item.cpp index 4998b37c..2eec3783 100644 --- a/src/otclient/item.cpp +++ b/src/otclient/item.cpp @@ -58,7 +58,7 @@ ItemPtr Item::createFromOtb(int id) return item; } -void Item::draw(const Point& dest, float scaleFactor, bool animate) +void Item::draw(const Point& dest, float scaleFactor, bool animate, LightView *lightView) { if(m_clientId == 0) return; @@ -76,7 +76,7 @@ void Item::draw(const Point& dest, float scaleFactor, bool animate) int xPattern = 0, yPattern = 0, zPattern = 0; calculatePatterns(xPattern, yPattern, zPattern); - rawGetThingType()->draw(dest, scaleFactor, 0, xPattern, yPattern, zPattern, animationPhase); + rawGetThingType()->draw(dest, scaleFactor, 0, xPattern, yPattern, zPattern, animationPhase, lightView); } void Item::setId(uint32 id) diff --git a/src/otclient/item.h b/src/otclient/item.h index 18de0531..fde875ac 100644 --- a/src/otclient/item.h +++ b/src/otclient/item.h @@ -81,7 +81,7 @@ public: static ItemPtr create(int id); static ItemPtr createFromOtb(int id); - void draw(const Point& dest, float scaleFactor, bool animate); + void draw(const Point& dest, float scaleFactor, bool animate, LightView *lightView = nullptr); void setId(uint32 id); void setOtbId(uint16 id); diff --git a/src/otclient/lightview.cpp b/src/otclient/lightview.cpp new file mode 100644 index 00000000..c8f00bc5 --- /dev/null +++ b/src/otclient/lightview.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2010-2012 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "lightview.h" +#include "mapview.h" +#include +#include +#include +#include + +LightView::LightView() +{ + m_lightbuffer = g_framebuffers.getTemporaryFrameBuffer(); + generateLightBuble(); + reset(); +} + +void LightView::generateLightBuble() +{ + const int size = 256; + uint8_t dest[size*size*4]; + + for(int x = 0; x < size; x++){ + for(int y = 0; y < size; y++){ + int norm = std::sqrt((size/2 - x)*(size/2 - x) + (size/2 - y)*(size/2 - y)); + float p = 128*norm/(size/2); + + float color = (p <= 128 ? 255 * (128-p)*(128-p)/(128*128) : 0); + if(color < 0) + color = 0; + + int line = y; + + dest[4*x + 4*size*line] = (uint8_t)color; + dest[4*x + 4*size*line + 1] = (uint8_t)color; + dest[4*x + 4*size*line + 2] = (uint8_t)color; + dest[4*x + 4*size*line + 3] = 255; + } + } + + ImagePtr light = ImagePtr(new Image(Size(size,size), 4, dest)); + m_lightTexture = TexturePtr(new Texture(light, false)); + m_lightTexture->setSmooth(true); +} + +void LightView::reset() +{ + m_numLights = 0; +} + +void LightView::setGlobalLight(const Light& light) +{ + m_globalLight = light; +} + +void LightView::addLightSource(const Point& center, float scaleFactor, const Light& light) +{ + if(m_numLights > MAX_LIGHTS) + return; + + int radius = light.intensity * 64 * scaleFactor; + + m_lightMap[m_numLights].center = center; + m_lightMap[m_numLights].color = Color::from8bit(light.color); + m_lightMap[m_numLights].radius = radius; + m_numLights++; +} + +void LightView::drawGlobalLight(const Light& light) +{ + Color color = Color::from8bit(light.color); + float factor = 0;//std::max(256 - light.intensity, 0) / 256.0f; + color.setRed(color.rF() * factor); + color.setGreen(color.gF() * factor); + color.setBlue(color.bF() * factor); + color.setAlpha(1.0f); + g_painter->clear(color); +} + +void LightView::drawLightSource(const Point& center, const Color& color, int radius) +{ + Rect dest = Rect(center - Point(radius, radius), Size(radius*2,radius*2)); + g_painter->setColor(color); + g_painter->drawTexturedRect(dest, m_lightTexture); + + // debug draw + //g_painter->drawBoundingRect(dest); +} + +void LightView::draw(Size size) +{ + m_lightbuffer->resize(size); + m_lightbuffer->bind(); + drawGlobalLight(m_globalLight); + g_painter->setCompositionMode(Painter::CompositionMode_Add); + for(int i=0;irelease(); + + g_painter->setCompositionMode(Painter::CompositionMode_Light); + m_lightbuffer->draw(); + g_painter->setCompositionMode(Painter::CompositionMode_Normal); +} diff --git a/src/otclient/lightview.h b/src/otclient/lightview.h new file mode 100644 index 00000000..6ad86799 --- /dev/null +++ b/src/otclient/lightview.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2010-2012 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef LIGHTVIEW_H +#define LIGHTVIEW_H + +#include "declarations.h" +#include +#include "thingtype.h" + +struct LightSource { + Color color; + Point center; + int radius; +}; + +class LightView : public LuaObject +{ + enum { + MAX_LIGHTS = 1024 + }; + +public: + LightView(); + + void reset(); + void setGlobalLight(const Light& light); + void addLightSource(const Point& center, float scaleFactor, const Light& light); + void draw(Size size); + +private: + void drawGlobalLight(const Light& light); + void drawLightSource(const Point& center, const Color& color, int radius); + void generateLightBuble(); + + TexturePtr m_lightTexture; + FrameBufferPtr m_lightbuffer; + MapView* m_mapView; + int m_numLights; + Light m_globalLight; + std::array m_lightMap; +}; + +#endif // LIGHTVIEW_H diff --git a/src/otclient/luafunctions.cpp b/src/otclient/luafunctions.cpp index 1cb9d4e1..2875d10c 100644 --- a/src/otclient/luafunctions.cpp +++ b/src/otclient/luafunctions.cpp @@ -517,6 +517,7 @@ void OTClient::registerLuaFunctions() g_lua.bindClassMemberFunction("setDrawFlags", &UIMap::setDrawFlags); g_lua.bindClassMemberFunction("setDrawTexts", &UIMap::setDrawTexts); g_lua.bindClassMemberFunction("setDrawMinimapColors", &UIMap::setDrawMinimapColors); + g_lua.bindClassMemberFunction("setDrawLights", &UIMap::setDrawLights); g_lua.bindClassMemberFunction("setAnimated", &UIMap::setAnimated); g_lua.bindClassMemberFunction("setKeepAspectRatio", &UIMap::setKeepAspectRatio); g_lua.bindClassMemberFunction("setMapShader", &UIMap::setMapShader); @@ -524,6 +525,7 @@ void OTClient::registerLuaFunctions() g_lua.bindClassMemberFunction("isAutoViewModeEnabled", &UIMap::isAutoViewModeEnabled); g_lua.bindClassMemberFunction("isDrawingTexts", &UIMap::isDrawingTexts); g_lua.bindClassMemberFunction("isDrawingMinimapColors", &UIMap::isDrawingMinimapColors); + g_lua.bindClassMemberFunction("isDrawingLights", &UIMap::isDrawingLights); g_lua.bindClassMemberFunction("isAnimating", &UIMap::isAnimating); g_lua.bindClassMemberFunction("isKeepAspectRatioEnabled", &UIMap::isKeepAspectRatioEnabled); g_lua.bindClassMemberFunction("getVisibleDimension", &UIMap::getVisibleDimension); diff --git a/src/otclient/mapview.cpp b/src/otclient/mapview.cpp index 953e74c4..b2ec5c0b 100644 --- a/src/otclient/mapview.cpp +++ b/src/otclient/mapview.cpp @@ -29,11 +29,14 @@ #include "animatedtext.h" #include "missile.h" #include "shadermanager.h" +#include "lightview.h" #include +#include #include #include #include +#include enum { @@ -86,6 +89,15 @@ void MapView::draw(const Rect& rect) drawFlags = Otc::DrawGround | Otc::DrawGroundBorders | Otc::DrawWalls | Otc::DrawItems; Size tileSize = Size(1,1) * m_tileSize; + + if(m_drawLights) { + m_lightView->reset(); + Light globalLight = g_map.getLight(); + if(cameraPosition.z <= 7) + globalLight.intensity = std::min(200, globalLight.intensity); + m_lightView->setGlobalLight(globalLight); + } + if(m_mustDrawVisibleTilesCache || (drawFlags & Otc::DrawAnimations)) { m_framebuffer->bind(); @@ -99,6 +111,7 @@ void MapView::draw(const Rect& rect) auto it = m_cachedVisibleTiles.begin(); auto end = m_cachedVisibleTiles.end(); for(int z=m_cachedLastVisibleFloor;z>=m_cachedFirstVisibleFloor;--z) { + while(it != end) { const TilePtr& tile = *it; Position tilePos = tile->getPosition(); @@ -108,7 +121,7 @@ void MapView::draw(const Rect& rect) ++it; if(!m_drawMinimapColors) - tile->draw(transformPositionTo2D(tilePos, cameraPosition), scaleFactor, drawFlags); + tile->draw(transformPositionTo2D(tilePos, cameraPosition), scaleFactor, drawFlags, m_lightView.get()); else { uint8 c = tile->getMinimapColorByte(); if(c == 0) @@ -121,7 +134,7 @@ void MapView::draw(const Rect& rect) if(drawFlags & Otc::DrawMissiles && !m_drawMinimapColors) { for(const MissilePtr& missile : g_map.getFloorMissiles(z)) { - missile->draw(transformPositionTo2D(missile->getPosition(), cameraPosition), scaleFactor, drawFlags & Otc::DrawAnimations); + missile->draw(transformPositionTo2D(missile->getPosition(), cameraPosition), scaleFactor, drawFlags & Otc::DrawAnimations, m_lightView.get()); } } } @@ -134,6 +147,11 @@ void MapView::draw(const Rect& rect) m_mustDrawVisibleTilesCache = false; } + if(m_drawLights) { + m_framebuffer->bind(); + m_lightView->draw(m_framebuffer->getSize()); + m_framebuffer->release(); + } Point drawOffset = ((m_drawDimension - m_visibleDimension - Size(1,1)).toPoint()/2) * m_tileSize; if(isFollowingCreature()) @@ -450,7 +468,6 @@ void MapView::updateGeometry(const Size& visibleDimension, const Size& optimized m_visibleCenterOffset = visibleCenterOffset; m_optimizedSize = optimizedSize; m_framebuffer->resize(bufferSize); - requestVisibleTilesCacheUpdate(); } @@ -631,3 +648,11 @@ void MapView::setDrawMinimapColors(bool enable) m_framebuffer->setSmooth(m_smooth); } +void MapView::setDrawLights(bool enable) +{ + if(enable) + m_lightView = LightViewPtr(new LightView); + else + m_lightView = nullptr; + m_drawLights = enable; +} diff --git a/src/otclient/mapview.h b/src/otclient/mapview.h index e01d4aab..eee84ad1 100644 --- a/src/otclient/mapview.h +++ b/src/otclient/mapview.h @@ -101,6 +101,9 @@ public: void setAnimated(bool animated) { m_animated = animated; requestVisibleTilesCacheUpdate(); } bool isAnimating() { return m_animated; } + void setDrawLights(bool enable); + bool isDrawingLights() { return m_drawLights; } + void setShader(const PainterShaderProgramPtr& shader) { m_shader = shader; } PainterShaderProgramPtr getShader() { return m_shader; } @@ -135,6 +138,7 @@ private: stdext::boolean m_drawTexts; stdext::boolean m_smooth; stdext::boolean m_drawMinimapColors; + stdext::boolean m_drawLights; stdext::boolean m_follow; std::vector m_cachedVisibleTiles; std::vector m_cachedFloorVisibleCreatures; @@ -144,6 +148,7 @@ private: ViewMode m_viewMode; Otc::DrawFlags m_drawFlags; std::vector m_spiral; + LightViewPtr m_lightView; }; #endif diff --git a/src/otclient/missile.cpp b/src/otclient/missile.cpp index c4dbf0e8..93efad2f 100644 --- a/src/otclient/missile.cpp +++ b/src/otclient/missile.cpp @@ -27,7 +27,7 @@ #include #include -void Missile::draw(const Point& dest, float scaleFactor, bool animate) +void Missile::draw(const Point& dest, float scaleFactor, bool animate, LightView *lightView) { if(m_id == 0 || !animate) return; @@ -63,7 +63,7 @@ void Missile::draw(const Point& dest, float scaleFactor, bool animate) } float fraction = m_animationTimer.ticksElapsed() / m_duration; - rawGetThingType()->draw(dest + m_delta * fraction * scaleFactor, scaleFactor, 0, xPattern, yPattern, 0, 0); + rawGetThingType()->draw(dest + m_delta * fraction * scaleFactor, scaleFactor, 0, xPattern, yPattern, 0, 0, lightView); } void Missile::setPath(const Position& fromPosition, const Position& toPosition) diff --git a/src/otclient/missile.h b/src/otclient/missile.h index 6dc63088..eecddb97 100644 --- a/src/otclient/missile.h +++ b/src/otclient/missile.h @@ -35,7 +35,7 @@ class Missile : public Thing }; public: - void draw(const Point& dest, float scaleFactor, bool animate); + void draw(const Point& dest, float scaleFactor, bool animate, LightView *lightView = nullptr); void setId(uint32 id); void setPath(const Position& fromPosition, const Position& toPosition); diff --git a/src/otclient/thing.h b/src/otclient/thing.h index fb7bc52f..0fbc831a 100644 --- a/src/otclient/thing.h +++ b/src/otclient/thing.h @@ -36,7 +36,7 @@ public: Thing(); virtual ~Thing() { } - virtual void draw(const Point& dest, float scaleFactor, bool animate) { } + virtual void draw(const Point& dest, float scaleFactor, bool animate, LightView *lightView = nullptr) { } virtual void setId(uint32 id) { } void setPosition(const Position& position); diff --git a/src/otclient/thingtype.cpp b/src/otclient/thingtype.cpp index c75c6068..f05f221f 100644 --- a/src/otclient/thingtype.cpp +++ b/src/otclient/thingtype.cpp @@ -23,6 +23,7 @@ #include "thingtype.h" #include "spritemanager.h" #include "game.h" +#include "lightview.h" #include #include @@ -138,7 +139,7 @@ void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileS m_texturesFramesOffsets.resize(m_animationPhases); } -void ThingType::draw(const Point& dest, float scaleFactor, int layer, int xPattern, int yPattern, int zPattern, int animationPhase) +void ThingType::draw(const Point& dest, float scaleFactor, int layer, int xPattern, int yPattern, int zPattern, int animationPhase, LightView *lightView) { if(m_null) return; @@ -160,6 +161,12 @@ void ThingType::draw(const Point& dest, float scaleFactor, int layer, int xPatte textureRect.size() * scaleFactor); g_painter->drawTexturedRect(screenRect, texture, textureRect); + + if(lightView && hasLight()) { + Light light = getLight(); + if(light.intensity > 0) + lightView->addLightSource(screenRect.center(), scaleFactor, light); + } } const TexturePtr& ThingType::getTexture(int animationPhase) diff --git a/src/otclient/thingtype.h b/src/otclient/thingtype.h index e53b45a4..1c19e711 100644 --- a/src/otclient/thingtype.h +++ b/src/otclient/thingtype.h @@ -107,7 +107,7 @@ public: void unserialize(uint16 clientId, ThingCategory category, const FileStreamPtr& fin); - void draw(const Point& dest, float scaleFactor, int layer, int xPattern, int yPattern, int zPattern, int animationPhase); + void draw(const Point& dest, float scaleFactor, int layer, int xPattern, int yPattern, int zPattern, int animationPhase, LightView *lightView = nullptr); uint16 getId() { return m_id; } ThingCategory getCategory() { return m_category; } diff --git a/src/otclient/tile.cpp b/src/otclient/tile.cpp index 61d034f0..943ab587 100644 --- a/src/otclient/tile.cpp +++ b/src/otclient/tile.cpp @@ -37,7 +37,7 @@ Tile::Tile(const Position& position) : { } -void Tile::draw(const Point& dest, float scaleFactor, int drawFlags) +void Tile::draw(const Point& dest, float scaleFactor, int drawFlags, LightView *lightView) { bool animate = drawFlags & Otc::DrawAnimations; @@ -50,8 +50,9 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags) if((thing->isGround() && drawFlags & Otc::DrawGround) || (thing->isGroundBorder() && drawFlags & Otc::DrawGroundBorders) || - (thing->isOnBottom() && drawFlags & Otc::DrawOnBottom)) - thing->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate); + (thing->isOnBottom() && drawFlags & Otc::DrawOnBottom)) { + thing->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView); + } m_drawElevation += thing->getElevation(); if(m_drawElevation > Otc::MAX_ELEVATION) @@ -68,7 +69,7 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags) const ThingPtr& thing = *it; if(thing->isOnTop() || thing->isOnBottom() || thing->isGroundBorder() || thing->isGround() || thing->isCreature()) break; - thing->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate); + thing->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView); if(thing->isLyingCorpse()) { redrawPreviousTopW = std::max(thing->getWidth(), redrawPreviousTopW); @@ -91,7 +92,7 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags) continue; const TilePtr& tile = g_map.getTile(m_position.translated(x,y)); if(tile) - tile->draw(dest + Point(x*Otc::TILE_PIXELS, y*Otc::TILE_PIXELS)*scaleFactor, scaleFactor, topRedrawFlags); + tile->draw(dest + Point(x*Otc::TILE_PIXELS, y*Otc::TILE_PIXELS)*scaleFactor, scaleFactor, topRedrawFlags, lightView); } } } @@ -102,8 +103,7 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags) if(animate) { for(const CreaturePtr& creature : m_walkingCreatures) { creature->draw(Point(dest.x + ((creature->getPosition().x - m_position.x)*Otc::TILE_PIXELS - m_drawElevation)*scaleFactor, - dest.y + ((creature->getPosition().y - m_position.y)*Otc::TILE_PIXELS - m_drawElevation)*scaleFactor), scaleFactor, animate); - + dest.y + ((creature->getPosition().y - m_position.y)*Otc::TILE_PIXELS - m_drawElevation)*scaleFactor), scaleFactor, animate, lightView); } } @@ -113,21 +113,24 @@ void Tile::draw(const Point& dest, float scaleFactor, int drawFlags) continue; CreaturePtr creature = thing->static_self_cast(); if(creature && (!creature->isWalking() || !animate)) - creature->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate); + creature->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView); + } } // effects if(drawFlags & Otc::DrawEffects) { - for(const EffectPtr& effect : m_effects) - effect->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate); + for(const EffectPtr& effect : m_effects){ + effect->draw(dest - m_drawElevation*scaleFactor, scaleFactor, animate, lightView); + } } // top items if(drawFlags & Otc::DrawOnTop) { for(const ThingPtr& thing : m_things) { - if(thing->isOnTop()) - thing->draw(dest, scaleFactor, animate); + if(thing->isOnTop()){ + thing->draw(dest, scaleFactor, animate, lightView); + } } } } diff --git a/src/otclient/tile.h b/src/otclient/tile.h index 4a2365ad..4a755231 100644 --- a/src/otclient/tile.h +++ b/src/otclient/tile.h @@ -24,6 +24,7 @@ #define TILE_H #include "declarations.h" +#include "mapview.h" #include "effect.h" #include "creature.h" #include "item.h" @@ -59,7 +60,7 @@ public: Tile(const Position& position); - void draw(const Point& dest, float scaleFactor, int drawFlags); + void draw(const Point& dest, float scaleFactor, int drawFlags, LightView *lightView = nullptr); public: void clean(); diff --git a/src/otclient/uimap.cpp b/src/otclient/uimap.cpp index 76c8f509..1c71f9c9 100644 --- a/src/otclient/uimap.cpp +++ b/src/otclient/uimap.cpp @@ -181,6 +181,8 @@ void UIMap::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleN setDrawTexts(node->value()); else if(node->tag() == "draw-minimap-colors") setDrawMinimapColors(node->value()); + else if(node->tag() == "draw-lights") + setDrawLights(node->value()); else if(node->tag() == "animated") setAnimated(node->value()); } diff --git a/src/otclient/uimap.h b/src/otclient/uimap.h index 0fc6c8a5..ad76338f 100644 --- a/src/otclient/uimap.h +++ b/src/otclient/uimap.h @@ -52,6 +52,7 @@ public: void setDrawFlags(Otc::DrawFlags drawFlags) { m_mapView->setDrawFlags(drawFlags); } void setDrawTexts(bool enable) { m_mapView->setDrawTexts(enable); } void setDrawMinimapColors(bool enable) { m_mapView->setDrawMinimapColors(enable); } + void setDrawLights(bool enable) { m_mapView->setDrawLights(enable); } void setAnimated(bool enable) { m_mapView->setAnimated(enable); } void setKeepAspectRatio(bool enable); void setMapShader(const PainterShaderProgramPtr& shader) { m_mapView->setShader(shader); } @@ -60,6 +61,7 @@ public: bool isAutoViewModeEnabled() { return m_mapView->isAutoViewModeEnabled(); } bool isDrawingTexts() { return m_mapView->isDrawingTexts(); } bool isDrawingMinimapColors() { return m_mapView->isDrawingMinimapColors(); } + bool isDrawingLights() { return m_mapView->isDrawingLights(); } bool isAnimating() { return m_mapView->isAnimating(); } bool isKeepAspectRatioEnabled() { return m_aspectRatio != 0.0f; }