Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions modules/client_options/graphics.otui
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ Panel
id: dontStretchShrink
!text: tr('Don\'t stretch/shrink Game Window')

OptionCheckBox
id: asyncTxtLoading
!text: tr('Async texture loading')

Label
id: floorViewModeLabel
!text: tr('Floor View Mode')..':'
Expand Down
5 changes: 4 additions & 1 deletion modules/client_options/options.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ local defaultOptions = {
forceEffectOptimization = false,
drawEffectOnTop = false,
floorViewMode = 1,
floorFading = 500
floorFading = 500,
asyncTxtLoading = true
}

local optionsWindow
Expand Down Expand Up @@ -215,6 +216,8 @@ function setOption(key, value, force)
g_app.forceEffectOptimization(value)
elseif key == 'drawEffectOnTop' then
g_app.setDrawEffectOnTop(value)
elseif key == 'asyncTxtLoading' then
g_app.setLoadingAsyncTexture(value)
elseif key == 'showPing' then
modules.client_topmenu.setPingVisible(value)
elseif key == 'fullscreen' then
Expand Down
2 changes: 1 addition & 1 deletion modules/game_interface/gameinterface.lua
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ function onSelectPanel(self, checked)
end

function bindKeys()
gameRootPanel:setAutoRepeatDelay(75)
gameRootPanel:setAutoRepeatDelay(50)

bindWalkKey('Up', North)
bindWalkKey('Right', East)
Expand Down
2 changes: 1 addition & 1 deletion src/client/attachedeffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void AttachedEffect::draw(const Point& dest, bool isOnTop, LightView* lightView)
return;

if (m_shader) g_drawPool.setShaderProgram(m_shader, true);
m_thingType->draw(dest - (dirControl.offset * g_drawPool.getScaleFactor()), 0, m_direction, 0, 0, getCurrentAnimationPhase(), Otc::DrawThingsAndLights, TextureType::NONE, Color::white, lightView);
m_thingType->draw(dest - (dirControl.offset * g_drawPool.getScaleFactor()), 0, m_direction, 0, 0, getCurrentAnimationPhase(), Otc::DrawThingsAndLights, Color::white, lightView);
}

int AttachedEffect::getCurrentAnimationPhase()
Expand Down
129 changes: 43 additions & 86 deletions src/client/creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Creature::Creature() :m_type(Proto::CreatureTypeUnknown)
*/
}

void Creature::draw(const Point& dest, uint32_t flags, TextureType textureType, bool isMarked, LightView* lightView)
void Creature::draw(const Point& dest, uint32_t flags, LightView* lightView)
{
if (!canBeSeen())
return;
Expand All @@ -76,10 +76,12 @@ void Creature::draw(const Point& dest, uint32_t flags, TextureType textureType,

const auto& _dest = dest + m_walkOffset * g_drawPool.getScaleFactor();

internalDrawOutfit(_dest, textureType, Color::white, lightView);
internalDraw(_dest, false, Color::white, lightView);

if (isMarked) {
internalDrawOutfit(_dest, TextureType::ALL_BLANK, getMarkedColor());
if (isMarked()) {
g_drawPool.setShaderProgram(g_painter->getReplaceColorShader());
internalDraw(_dest, true, getMarkedColor());
g_drawPool.resetShaderProgram();
}
}

Expand All @@ -100,18 +102,11 @@ void Creature::draw(const Point& dest, uint32_t flags, TextureType textureType,
}
}

void Creature::internalDrawOutfit(Point dest, TextureType textureType, const Color& color, LightView* lightView)
void Creature::internalDraw(Point dest, bool isMarked, const Color& color, LightView* lightView)
{
const auto& newColor = m_outfitColor != Color::white ? m_outfitColor : color;

const bool isNotBlank = textureType != TextureType::ALL_BLANK;
const bool canDrawShader = isNotBlank;

int animationPhase = 0;

if (isNotBlank) {
drawAttachedEffect(dest, lightView, false); // On Bottom
}
drawAttachedEffect(dest, lightView, false); // On Bottom

// outfit is a real creature
if (m_outfit.getCategory() == ThingCategoryCreature) {
Expand All @@ -120,9 +115,9 @@ void Creature::internalDrawOutfit(Point dest, TextureType textureType, const Col

dest -= m_mountType->getDisplacement() * g_drawPool.getScaleFactor();

if (canDrawShader && m_mountShader)
if (!isMarked && m_mountShader)
g_drawPool.setShaderProgram(m_mountShader, true, m_mountShaderAction);
m_mountType->draw(dest, 0, m_numPatternX, 0, 0, animationPhase, Otc::DrawThingsAndLights, textureType, newColor);
m_mountType->draw(dest, 0, m_numPatternX, 0, 0, animationPhase, Otc::DrawThingsAndLights, color);
dest += getDisplacement() * g_drawPool.getScaleFactor();
}

Expand All @@ -141,16 +136,17 @@ void Creature::internalDrawOutfit(Point dest, TextureType textureType, const Col
if (yPattern > 0 && !(m_outfit.getAddons() & (1 << (yPattern - 1))))
continue;

if (canDrawShader && m_shader)
if (!isMarked && m_shader)
g_drawPool.setShaderProgram(m_shader, true, m_shaderAction);
datType->draw(dest, 0, m_numPatternX, yPattern, m_numPatternZ, animationPhase, Otc::DrawThingsAndLights, textureType, newColor);

if (m_drawOutfitColor && isNotBlank && getLayers() > 1) {
datType->draw(dest, 0, m_numPatternX, yPattern, m_numPatternZ, animationPhase, Otc::DrawThingsAndLights, color);

if (m_drawOutfitColor && !isMarked && getLayers() > 1) {
g_drawPool.setCompositionMode(CompositionMode::MULTIPLY);
datType->draw(dest, SpriteMaskYellow, m_numPatternX, yPattern, m_numPatternZ, animationPhase, Otc::DrawThingsAndLights, textureType, m_outfit.getHeadColor());
datType->draw(dest, SpriteMaskRed, m_numPatternX, yPattern, m_numPatternZ, animationPhase, Otc::DrawThingsAndLights, textureType, m_outfit.getBodyColor());
datType->draw(dest, SpriteMaskGreen, m_numPatternX, yPattern, m_numPatternZ, animationPhase, Otc::DrawThingsAndLights, textureType, m_outfit.getLegsColor());
datType->draw(dest, SpriteMaskBlue, m_numPatternX, yPattern, m_numPatternZ, animationPhase, Otc::DrawThingsAndLights, textureType, m_outfit.getFeetColor());
datType->draw(dest, SpriteMaskYellow, m_numPatternX, yPattern, m_numPatternZ, animationPhase, Otc::DrawThingsAndLights, m_outfit.getHeadColor());
datType->draw(dest, SpriteMaskRed, m_numPatternX, yPattern, m_numPatternZ, animationPhase, Otc::DrawThingsAndLights, m_outfit.getBodyColor());
datType->draw(dest, SpriteMaskGreen, m_numPatternX, yPattern, m_numPatternZ, animationPhase, Otc::DrawThingsAndLights, m_outfit.getLegsColor());
datType->draw(dest, SpriteMaskBlue, m_numPatternX, yPattern, m_numPatternZ, animationPhase, Otc::DrawThingsAndLights, m_outfit.getFeetColor());
g_drawPool.resetCompositionMode();
}
}
Expand All @@ -174,27 +170,33 @@ void Creature::internalDrawOutfit(Point dest, TextureType textureType, const Col
if (m_outfit.getCategory() == ThingCategoryEffect)
animationPhase = std::min<int>(animationPhase + 1, animationPhases);

if (canDrawShader && m_shader)
if (isMarked && m_shader)
g_drawPool.setShaderProgram(m_shader, true, m_shaderAction);
m_thingType->draw(dest - (getDisplacement() * g_drawPool.getScaleFactor()), 0, 0, 0, 0, animationPhase, Otc::DrawThingsAndLights, textureType, newColor);
m_thingType->draw(dest - (getDisplacement() * g_drawPool.getScaleFactor()), 0, 0, 0, 0, animationPhase, Otc::DrawThingsAndLights, color);
}

if (isNotBlank) {
drawAttachedEffect(dest, lightView, true); // On Top
}
drawAttachedEffect(dest, lightView, true); // On Top
}

void Creature::drawOutfit(const Rect& destRect, bool resize, const Color& color)
{
if (!m_thingType)
return;

// ExactSize Cache
if (m_exactSize == 0) {
if (m_exactSize = getExactSize()) {
m_exactSize = std::max<uint8_t>(m_exactSize, SPRITE_SIZE);
m_frameSizeNotResized = std::max<int>(m_exactSize * 0.75f, 2 * SPRITE_SIZE * 0.75f);
}
}

const uint8_t frameSize = resize ? m_exactSize : m_frameSizeNotResized;
if (frameSize == 0)
return;

g_drawPool.bindFrameBuffer(frameSize);
internalDrawOutfit(Point(frameSize - SPRITE_SIZE) + getDisplacement(), TextureType::NONE, color);
internalDraw(Point(frameSize - SPRITE_SIZE) + getDisplacement(), false, color);
g_drawPool.releaseFrameBuffer(destRect);
}

Expand Down Expand Up @@ -683,72 +685,24 @@ void Creature::setOutfit(const Outfit& outfit)
if (m_outfit == outfit)
return;

const Outfit oldOutfit = m_outfit;

m_outfit = outfit;
m_thingType = nullptr;
m_mountType = nullptr;
m_numPatternZ = 0;

const Outfit oldOutfit = m_outfit;
if (outfit.getCategory() != ThingCategoryCreature) {
if (!g_things.isValidDatId(outfit.getAuxId(), outfit.getCategory()))
return;

m_outfit.setAuxId(outfit.getAuxId());
m_outfit.setCategory(outfit.getCategory());
m_thingType = g_things.getThingType(m_outfit.getAuxId(), m_outfit.getCategory()).get();

m_exactSize = g_things.getThingType(m_outfit.getAuxId(), m_outfit.getCategory())->getExactSize();
} else {
if (outfit.getId() > 0 && !g_things.isValidDatId(outfit.getId(), ThingCategoryCreature))
return;

m_outfit = outfit;
m_thingType = g_things.getThingType(m_outfit.getId(), ThingCategoryCreature).get();
if (m_outfit.hasMount()) {
m_mountType = g_things.getThingType(m_outfit.getMount(), ThingCategoryCreature).get();
m_numPatternZ = std::min<int>(1, getNumPatternZ() - 1);
}

m_exactSize = getExactSize();
}

m_exactSize = 0;
m_frameSizeNotResized = 0;
m_walkAnimationPhase = 0; // might happen when player is walking and outfit is changed.
m_exactSize = std::max<uint8_t>(m_exactSize, SPRITE_SIZE);
m_frameSizeNotResized = std::max<int>(m_exactSize * 0.75f, 2 * SPRITE_SIZE * 0.75f);

callLuaField("onOutfitChange", m_outfit, oldOutfit);
}

void Creature::setOutfitColor(const Color& color, int duration)
{
if (m_outfitColorUpdateEvent) {
m_outfitColorUpdateEvent->cancel();
m_outfitColorUpdateEvent = nullptr;
}
m_thingType = g_things.getThingType(m_outfit.isCreature() ? m_outfit.getId() : m_outfit.getAuxId(), m_outfit.getCategory()).get();

if (duration <= 0) {
m_outfitColor = color;
return;
if (m_outfit.hasMount()) {
m_mountType = g_things.getThingType(m_outfit.getMount(), ThingCategoryCreature).get();
m_numPatternZ = std::min<int>(1, getNumPatternZ() - 1);
}

m_outfitColorTimer.restart();

const auto& delta = (color - m_outfitColor) / static_cast<float>(duration);
updateOutfitColor(m_outfitColor, color, delta, duration);
}

void Creature::updateOutfitColor(Color color, Color finalColor, Color delta, int duration)
{
if (m_outfitColorTimer.ticksElapsed() >= duration) {
m_outfitColor = finalColor;
return;
}

m_outfitColor = color + delta * m_outfitColorTimer.ticksElapsed();

const auto self = static_self_cast<Creature>();
m_outfitColorUpdateEvent = g_dispatcher.scheduleEvent([=] {
self->updateOutfitColor(color, finalColor, delta, duration);
}, 100);
callLuaField("onOutfitChange", m_outfit, oldOutfit);
}

void Creature::setSpeed(uint16_t speed)
Expand Down Expand Up @@ -945,6 +899,9 @@ uint16_t Creature::getCurrentAnimationPhase(const bool mount)

int Creature::getExactSize(int layer, int xPattern, int yPattern, int zPattern, int animationPhase)
{
if (!m_outfit.isCreature())
return m_thingType->getExactSize();

const int numPatternY = getNumPatternY();

zPattern = m_outfit.hasMount() ? 1 : 0;
Expand Down
10 changes: 3 additions & 7 deletions src/client/creature.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ class Creature : public Thing
void onAppear() override;
void onDisappear() override;

void draw(const Point& dest, uint32_t flags, TextureType textureType, bool isMarked = false, LightView* lightView = nullptr) override;
void draw(const Point& dest, uint32_t flags, LightView* lightView = nullptr) override;

void internalDrawOutfit(Point dest, TextureType textureType, const Color& color, LightView* lightView = nullptr);
void internalDraw(Point dest, bool isMarked, const Color& color, LightView* lightView = nullptr);

void drawOutfit(const Rect& destRect, bool resize, const Color& color = Color::white);
void drawInformation(const MapPosInfo& mapRect, const Point& dest, bool useGray, int drawFlags);
Expand All @@ -64,7 +64,6 @@ class Creature : public Thing
void setHealthPercent(uint8_t healthPercent);
void setDirection(Otc::Direction direction);
void setOutfit(const Outfit& outfit);
void setOutfitColor(const Color& color, int duration);
void setLight(const Light& light) { m_light = light; }
void setSpeed(uint16_t speed);
void setBaseSpeed(uint16_t baseSpeed);
Expand Down Expand Up @@ -134,7 +133,7 @@ class Creature : public Thing
bool isPassable() const { return m_passable; }
bool isWalking() { return m_walking; }
bool isRemoved() { return m_removed; }
bool isInvisible() { return m_outfit.getCategory() == ThingCategoryEffect && m_outfit.getAuxId() == 13; }
bool isInvisible() { return m_outfit.isEffect() && m_outfit.getAuxId() == 13; }
bool isDead() { return m_healthPercent <= 0; }
bool isFullHealth() const { return m_healthPercent == 100; }
bool canBeSeen() { return !isInvisible() || isPlayer(); }
Expand Down Expand Up @@ -172,8 +171,6 @@ class Creature : public Thing
void updateWalkingTile();
void updateWalkAnimation();

void updateOutfitColor(Color color, Color finalColor, Color delta, int duration);

uint16_t getCurrentAnimationPhase(bool mount = false);

struct CachedStep
Expand Down Expand Up @@ -235,7 +232,6 @@ class Creature : public Thing
Color m_timedSquareColor{ Color::white };
Color m_staticSquareColor{ Color::white };
Color m_informationColor{ Color::white };
Color m_outfitColor{ Color::white };

CachedText m_name;
CachedStep m_stepCache;
Expand Down
2 changes: 1 addition & 1 deletion src/client/effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ void Effect::drawEffect(const Point& dest, uint32_t flags, int offsetX, int offs
m_drawConductor.order = DrawOrder::FOURTH;
}

getThingType()->draw(dest, 0, xPattern, yPattern, 0, animationPhase, flags, TextureType::NONE, Color::white, lightView, m_drawConductor);
getThingType()->draw(dest, 0, xPattern, yPattern, 0, animationPhase, flags, Color::white, lightView, m_drawConductor);
}

void Effect::onAppear()
Expand Down
22 changes: 14 additions & 8 deletions src/client/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,25 +45,31 @@ ItemPtr Item::create(int id)
return item;
}

void Item::draw(const Point& dest, uint32_t flags, TextureType textureType, bool isMarked, LightView* lightView)
void Item::draw(const Point& dest, uint32_t flags, LightView* lightView)
{
if (m_clientId == 0 || !canDraw())
return;

// determine animation phase
const int animationPhase = calculateAnimationPhase();

drawAttachedEffect(dest, lightView, false); // On Bottom
if (textureType != TextureType::ALL_BLANK && m_shader)
g_drawPool.setShaderProgram(m_shader, true, m_shaderAction);
getThingType()->draw(dest, 0, m_numPatternX, m_numPatternY, m_numPatternZ, animationPhase, flags, textureType, m_color, lightView, m_drawConductor);
drawAttachedEffect(dest, lightView, true); // On Top
internalDraw(animationPhase, dest, m_color, flags, lightView);

if (isMarked) {
getThingType()->draw(dest, 0, m_numPatternX, m_numPatternY, m_numPatternZ, animationPhase, flags, TextureType::ALL_BLANK, getMarkedColor());
if (isMarked()) {
g_drawPool.setShaderProgram(g_painter->getReplaceColorShader());
internalDraw(animationPhase, dest, getMarkedColor(), flags);
g_drawPool.resetShaderProgram();
}
}

void Item::internalDraw(int animationPhase, const Point& dest, const Color& color, uint32_t flags, LightView* lightView)
{
drawAttachedEffect(dest, lightView, false); // On Bottom
if (m_shader) g_drawPool.setShaderProgram(m_shader, true, m_shaderAction);
getThingType()->draw(dest, 0, m_numPatternX, m_numPatternY, m_numPatternZ, animationPhase, flags, color, lightView, m_drawConductor);
drawAttachedEffect(dest, lightView, true); // On Top
}

void Item::setConductor()
{
if (isSingleGround()) {
Expand Down
3 changes: 2 additions & 1 deletion src/client/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ class Item : public Thing
public:
static ItemPtr create(int id);

void draw(const Point& dest, uint32_t flags, TextureType textureType = TextureType::NONE, bool isMarked = false, LightView* lightView = nullptr) override;
void draw(const Point& dest, uint32_t flags, LightView* lightView = nullptr) override;
void internalDraw(int animationPhase, const Point& dest, const Color& color, uint32_t flags, LightView* lightView = nullptr);

void setId(uint32_t id) override;

Expand Down
3 changes: 2 additions & 1 deletion src/client/luafunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,8 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<Thing>("setId", &Thing::setId);
g_lua.bindClassMemberFunction<Thing>("setShader", &Thing::setShader);
g_lua.bindClassMemberFunction<Thing>("setPosition", &Thing::setPosition);
g_lua.bindClassMemberFunction<Thing>("setMarkColor", &Thing::setMarkColor);
g_lua.bindClassMemberFunction<Thing>("isMarked", &Thing::isMarked);
g_lua.bindClassMemberFunction<Thing>("getId", &Thing::getId);
g_lua.bindClassMemberFunction<Thing>("getTile", &Thing::getTile);
g_lua.bindClassMemberFunction<Thing>("getPosition", &Thing::getPosition);
Expand Down Expand Up @@ -496,7 +498,6 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<Creature>("getIcon", &Creature::getIcon);
g_lua.bindClassMemberFunction<Creature>("setOutfit", &Creature::setOutfit);
g_lua.bindClassMemberFunction<Creature>("getOutfit", &Creature::getOutfit);
g_lua.bindClassMemberFunction<Creature>("setOutfitColor", &Creature::setOutfitColor);
g_lua.bindClassMemberFunction<Creature>("getDirection", &Creature::getDirection);
g_lua.bindClassMemberFunction<Creature>("getStepDuration", &Creature::getStepDuration);
g_lua.bindClassMemberFunction<Creature>("getStepProgress", &Creature::getStepProgress);
Expand Down
2 changes: 1 addition & 1 deletion src/client/missile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ void Missile::drawMissile(const Point& dest, LightView* lightView)

const float fraction = m_animationTimer.ticksElapsed() / m_duration;
getThingType()->draw(dest + m_delta * fraction * g_drawPool.getScaleFactor(), 0, m_numPatternX, m_numPatternY, 0, 0,
Otc::DrawThings | Otc::DrawLights, TextureType::NONE, Color::white, lightView, m_drawConductor);
Otc::DrawThings | Otc::DrawLights, Color::white, lightView, m_drawConductor);
}

void Missile::setPath(const Position& fromPosition, const Position& toPosition)
Expand Down
Loading