Skip to content

Commit

Permalink
feat: Drawpool 3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
mehah authored Nov 27, 2023
1 parent 674ad54 commit 94fbbbc
Show file tree
Hide file tree
Showing 34 changed files with 557 additions and 501 deletions.
2 changes: 1 addition & 1 deletion init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Services = {

g_app.setName("OTClient - Redemption");
g_app.setCompactName("otclient");
g_app.setOrganizationName("otbr");
g_app.setOrganizationName("otcr");

g_app.hasUpdater = function()
return (Services.updater and Services.updater ~= "" and g_modules.getModule("updater"))
Expand Down
40 changes: 19 additions & 21 deletions modules/game_battle/battle.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-- Global Tables
local binaryTree = {} -- BST
local binaryTree = {} -- BST
local battleButtons = {} -- map of creature id

-- Global variables that will inherit from init
Expand Down Expand Up @@ -64,7 +64,7 @@ end
function init() -- Initiating the module (load)
g_ui.importStyle('battlebutton')
battleButton = modules.client_topmenu.addRightGameToggleButton('battleButton', tr('Battle') .. ' (Ctrl+B)',
'/images/topbuttons/battle', toggle)
'/images/topbuttons/battle', toggle)
battleButton:setOn(true)
battleWindow = g_ui.loadUI('battle')

Expand All @@ -88,14 +88,14 @@ function init() -- Initiating the module (load)
end

-- Adding Filter options
local options = {'hidePlayers', 'hideNPCs', 'hideMonsters', 'hideSkulls', 'hideParty'}
local options = { 'hidePlayers', 'hideNPCs', 'hideMonsters', 'hideSkulls', 'hideParty' }
for i, v in ipairs(options) do
hideButtons[v] = battleWindow:recursiveGetChildById(v)
end

-- Adding SortType and SortOrder options
local sortTypeOptions = {'Name', 'Distance', 'Age', 'Health'}
local sortOrderOptions = {'Asc.', 'Desc.'}
local sortTypeOptions = { 'Name', 'Distance', 'Age', 'Health' }
local sortOrderOptions = { 'Asc.', 'Desc.' }

local sortTypeBox = battleWindow:recursiveGetChildById('sortTypeBox')
for i, v in ipairs(sortTypeOptions) do
Expand Down Expand Up @@ -134,7 +134,6 @@ end

-- Binary Search, Insertion and Resort functions
local function debugTables(sortType) -- Print both battlebutton and binarytree tables

local function getInfo(v, sortType)
local returnedInfo = v.id
if sortType then
Expand Down Expand Up @@ -464,10 +463,14 @@ end

local function canBeSeen(creature)
return creature and creature:canBeSeen() and creature:getPosition() and
modules.game_interface.getMapPanel():isInRange(creature:getPosition())
modules.game_interface.getMapPanel():isInRange(creature:getPosition())
end

local function getDistanceBetween(p1, p2) -- Calculate distance
if p2 == nil then
p2 = { x = 0, y = 0 }
end

local xd = math.abs(p1.x - p2.x);
local yd = math.abs(p1.y - p2.y);

Expand Down Expand Up @@ -622,8 +625,8 @@ function removeCreature(creature, all) -- Remove a single creature or all
msg = msg .. p
end
assert(index ~= nil,
'Not able to remove creature: id ' .. creatureId .. ' not found in binary search using ' .. sortType ..
' to find value ' .. msg .. '.')
'Not able to remove creature: id ' .. creatureId .. ' not found in binary search using ' .. sortType ..
' to find value ' .. msg .. '.')
end
end
return false
Expand Down Expand Up @@ -688,10 +691,8 @@ function attackNext(previous)

if battleButton.isTarget then
foundTarget = true

elseif foundTarget and not nextElement then
nextElement = battleButton

elseif not foundTarget then
prevElement = battleButton
end
Expand All @@ -712,7 +713,6 @@ function attackNext(previous)
g_game.attack(firstElement.creature)
end
end

elseif firstElement then
g_game.attack(firstElement.creature)
else
Expand Down Expand Up @@ -896,9 +896,9 @@ function onCreaturePositionChange(creature, newPos, oldPos) -- Update battleButt
correctBattleButtons()
else
assert(index ~= nil,
'Not able to update Position Change. Creature: ' .. creature:getName() .. ' id ' ..
creatureId .. ' not found in binary search using ' .. sortType ..
' to find value ' .. oldDistance .. '.\n')
'Not able to update Position Change. Creature: ' .. creature:getName() .. ' id ' ..
creatureId .. ' not found in binary search using ' .. sortType ..
' to find value ' .. oldDistance .. '.\n')
end
end
end
Expand Down Expand Up @@ -952,11 +952,10 @@ function onCreatureHealthPercentChange(creature, healthPercent, oldHealthPercent
correctBattleButtons()
else
assert(index ~= nil,
'Not able to update HealthPercent Change. Creature: id ' .. creatureId ..
' not found in binary search using ' .. sortType .. ' to find value ' .. oldHealthPercent ..
'.')
'Not able to update HealthPercent Change. Creature: id ' .. creatureId ..
' not found in binary search using ' .. sortType .. ' to find value ' .. oldHealthPercent ..
'.')
end

end
battleButton:setLifeBarPercent(healthPercent)
end
Expand Down Expand Up @@ -986,7 +985,7 @@ function onBattleButtonMouseRelease(self, mousePosition, mouseButton) -- Interac
end

if ((g_mouse.isPressed(MouseLeftButton) and mouseButton == MouseRightButton) or
(g_mouse.isPressed(MouseRightButton) and mouseButton == MouseLeftButton)) then
(g_mouse.isPressed(MouseRightButton) and mouseButton == MouseLeftButton)) then
mouseWidget.cancelNextRelease = true
g_game.look(self.creature, true)
return true
Expand Down Expand Up @@ -1080,5 +1079,4 @@ function terminate() -- Terminating the Module (unload)
onGameStart = onGameStart
})
disconnecting()

end
3 changes: 2 additions & 1 deletion modules/game_features/features.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
controller = Controller:new()
controller:registerEvents(g_game, {
onClientVersionChange = function(version)
g_game.enableFeature(GameFormatCreatureName);
-- g_game.enableFeature(GameKeepUnawareTiles)
g_game.enableFeature(GameFormatCreatureName)

if version >= 750 then
g_game.enableFeature(GameSoul);
Expand Down
49 changes: 25 additions & 24 deletions src/client/lightview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,13 @@ LightView::LightView(const Size& size, const uint16_t tileSize) : m_pool(g_drawP
m_texture = std::make_shared<Texture>(size);
m_texture->setSmooth(true);
});

g_drawPool.use(DrawPoolType::LIGHT);
g_drawPool.addAction([this] {
{
std::scoped_lock l(m_pool->getMutex());
m_texture->updatePixels(m_pixels.data());
}
g_painter->resetColor();
g_painter->resetTransformMatrix();
g_painter->setTexture(m_texture.get());
g_painter->setCompositionMode(CompositionMode::MULTIPLY);
g_painter->drawCoords(m_coords);
});
}

void LightView::resize(const Size& size, const uint16_t tileSize) {
if (!m_texture || m_mapSize == size && m_tileSize == tileSize)
return;

std::scoped_lock l(m_pool->getMutex());
std::scoped_lock l(m_pool->getMutex(), m_pool->getMutexPreDraw());

m_mapSize = size;
m_tileSize = tileSize;
Expand All @@ -71,10 +58,10 @@ void LightView::resize(const Size& size, const uint16_t tileSize) {

void LightView::addLightSource(const Point& pos, const Light& light, float brightness)
{
if (light.intensity == 0)
if (!isDark() || light.intensity == 0)
return;

auto& lightData = m_lightData[m_currentLightData];
auto& lightData = m_lightData[0];

if (!lightData.lights.empty()) {
auto& prevLight = lightData.lights.back();
Expand All @@ -95,7 +82,7 @@ void LightView::addLightSource(const Point& pos, const Light& light, float brigh

void LightView::resetShade(const Point& pos)
{
auto& lightData = m_lightData[m_currentLightData];
auto& lightData = m_lightData[0];

size_t index = (pos.y / m_tileSize) * m_mapSize.width() + (pos.x / m_tileSize);
if (index >= lightData.tiles.size()) return;
Expand All @@ -104,20 +91,34 @@ void LightView::resetShade(const Point& pos)

void LightView::draw(const Rect& dest, const Rect& src)
{
updateCoords(dest, src);

if (m_updatedHash != m_hash) {
m_hash = m_updatedHash;
m_updatedHash = 0;

std::scoped_lock l(m_pool->getMutex());
if (++m_currentLightData > 1) m_currentLightData = 0;
std::scoped_lock l(m_pool->getMutexPreDraw());
std::swap(m_lightData[0], m_lightData[1]);
g_asyncDispatcher.dispatch([this] {
updatePixels();
});
}

auto& lightData = m_lightData[m_currentLightData];
g_drawPool.preDraw(DrawPoolType::LIGHT, [this, &dest, &src] {
g_drawPool.addAction([=, this] {
{
std::scoped_lock l(m_pool->getMutexPreDraw());
m_texture->updatePixels(m_pixels.data());
}

updateCoords(dest, src);
g_painter->setCompositionMode(CompositionMode::MULTIPLY);
g_painter->resetTransformMatrix();
g_painter->resetColor();
g_painter->setTexture(m_texture.get());
g_painter->drawCoords(m_coords);
});
});

auto& lightData = m_lightData[0];
lightData.lights.clear();
lightData.tiles.assign(m_mapSize.area(), {});
}
Expand All @@ -139,9 +140,9 @@ void LightView::updateCoords(const Rect& dest, const Rect& src) {
}

void LightView::updatePixels() {
std::scoped_lock l(m_pool->getMutex());
std::scoped_lock l(m_pool->getMutexPreDraw());

const auto& lightData = m_lightData[m_currentLightData ? 0 : 1];
const auto& lightData = m_lightData[1];

const size_t lightSize = lightData.lights.size();

Expand Down
1 change: 0 additions & 1 deletion src/client/lightview.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,5 @@ class LightView : public LuaObject
CoordsBuffer m_coords;
TexturePtr m_texture;
LightData m_lightData[2];
std::atomic_uint8_t m_currentLightData{ 0 };
std::vector<uint8_t> m_pixels;
};
66 changes: 35 additions & 31 deletions src/client/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,51 +152,55 @@ void Map::addStaticText(const StaticTextPtr& txt, const Position& pos) {
if (!g_app.isDrawingTexts())
return;

for (const auto& other : m_staticTexts) {
// try to combine messages
if (other->getPosition() == pos && other->addMessage(txt->getName(), txt->getMessageMode(), txt->getFirstMessage())) {
return;
g_textDispatcher.addEvent([=, this] {
for (const auto& other : m_staticTexts) {
// try to combine messages
if (other->getPosition() == pos && other->addMessage(txt->getName(), txt->getMessageMode(), txt->getFirstMessage())) {
return;
}
}
}

txt->setPosition(pos);
m_staticTexts.emplace_back(txt);
txt->setPosition(pos);
m_staticTexts.emplace_back(txt);
});
}

void Map::addAnimatedText(const AnimatedTextPtr& txt, const Position& pos) {
if (!g_app.isDrawingTexts())
return;

// this code will stack animated texts of the same color
AnimatedTextPtr prevAnimatedText;

bool merged = false;
for (const auto& other : m_animatedTexts) {
if (other->getPosition() == pos) {
prevAnimatedText = other;
if (other->merge(txt)) {
merged = true;
break;
g_textDispatcher.addEvent([=, this] {
// this code will stack animated texts of the same color
AnimatedTextPtr prevAnimatedText;

bool merged = false;
for (const auto& other : m_animatedTexts) {
if (other->getPosition() == pos) {
prevAnimatedText = other;
if (other->merge(txt)) {
merged = true;
break;
}
}
}
}

if (!merged) {
if (prevAnimatedText) {
Point offset = prevAnimatedText->getOffset();
if (const float t = prevAnimatedText->getTimer().ticksElapsed();
t < g_gameConfig.getAnimatedTextDuration() / 4.0) { // didnt move 12 pixels
const int32_t y = 12 - 48 * t / static_cast<float>(g_gameConfig.getAnimatedTextDuration());
offset += Point(0, y);
if (!merged) {
if (prevAnimatedText) {
Point offset = prevAnimatedText->getOffset();
if (const float t = prevAnimatedText->getTimer().ticksElapsed();
t < g_gameConfig.getAnimatedTextDuration() / 4.0) { // didnt move 12 pixels
const int32_t y = 12 - 48 * t / static_cast<float>(g_gameConfig.getAnimatedTextDuration());
offset += Point(0, y);
}
offset.y = std::min<int32_t>(offset.y, 12);
txt->setOffset(offset);
}
offset.y = std::min<int32_t>(offset.y, 12);
txt->setOffset(offset);
m_animatedTexts.emplace_back(txt);
}
m_animatedTexts.emplace_back(txt);
}

txt->setPosition(pos);
txt->onAppear();
txt->setPosition(pos);
txt->onAppear();
});
}

ThingPtr Map::getThing(const Position& pos, int16_t stackPos)
Expand Down
Loading

0 comments on commit 94fbbbc

Please sign in to comment.