Skip to content

Commit

Permalink
Now it is possible to attache effects to tiles and set where it will …
Browse files Browse the repository at this point in the history
…be drawn
  • Loading branch information
conde2 committed Nov 14, 2023
1 parent 82ecd7c commit ee322f7
Show file tree
Hide file tree
Showing 14 changed files with 275 additions and 110 deletions.
1 change: 1 addition & 0 deletions modules/gamelib/gamelib.otmod
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Module
dofile 'textmessages'
dofile 'thing'
dofile 'spells'
dofile 'tile'

dofile 'eventcontroller'
dofile 'controller'
Expand Down
4 changes: 4 additions & 0 deletions modules/gamelib/thing.lua
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,7 @@ SpriteMaskRed = 1
SpriteMaskGreen = 2
SpriteMaskBlue = 3
SpriteMaskYellow = 4

function Thing:isTile()
return false
end
39 changes: 39 additions & 0 deletions modules/gamelib/tile.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
function Tile:isTile()
return true
end

function Tile:isCreature()
return false
end

function Tile:isLocalPlayer()
return false
end

function Tile:isNpc()
return false
end

function Tile:isMonster()
return false
end

function Tile:isPlayer()
return false
end

function Tile:isEffect()
return false
end

function Tile:isMissile()
return false
end

function Tile:isItem()
return false
end

function Tile:isContainer()
return false
end
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ endif()
set(SOURCE_FILES
client/animatedtext.cpp
client/animator.cpp
client/attachableobject.cpp
client/attachedeffect.cpp
client/attachedeffectmanager.cpp
client/client.cpp
Expand Down
102 changes: 102 additions & 0 deletions src/client/attachableobject.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright (c) 2010-2022 OTClient <https://github.com/edubart/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 "attachableobject.h"
#include "tile.h"

#include <framework/core/eventdispatcher.h>
#include <framework/core/graphicalapplication.h>

void AttachableObject::attachEffect(const AttachedEffectPtr& obj) {
if (!obj)
return;

onStartAttachEffect(obj);

if (obj->isHidedOwner())
++m_ownerHidden;

if (obj->getDuration() > 0) {
g_dispatcher.scheduleEvent([self = std::static_pointer_cast<AttachableObject>(shared_from_this()), effectId = obj->getId()]() {
self->detachEffectById(effectId);
}, obj->getDuration());
}

m_attachedEffects.emplace_back(obj);
g_dispatcher.addEvent([effect = obj, self = std::static_pointer_cast<AttachableObject>(shared_from_this())] {
self->onDispatcherAttachEffect(effect);
effect->callLuaField("onAttach", self->attachedObjectToLuaObject());
});
}

bool AttachableObject::detachEffectById(uint16_t id) {
const auto it = std::find_if(m_attachedEffects.begin(), m_attachedEffects.end(),
[id](const AttachedEffectPtr& obj) { return obj->getId() == id; });

if (it == m_attachedEffects.end())
return false;

onDetachEffect(*it);
m_attachedEffects.erase(it);

return true;
}

void AttachableObject::onDetachEffect(const AttachedEffectPtr& effect) {
if (effect->isHidedOwner())
--m_ownerHidden;

onStartDetachEffect(effect);

effect->callLuaField("onDetach", attachedObjectToLuaObject());
}

void AttachableObject::clearAttachedEffects() {
for (const auto& e : m_attachedEffects)
onDetachEffect(e);
m_attachedEffects.clear();
}

AttachedEffectPtr AttachableObject::getAttachedEffectById(uint16_t id) {
const auto it = std::find_if(m_attachedEffects.begin(), m_attachedEffects.end(),
[id](const AttachedEffectPtr& obj) { return obj->getId() == id; });

if (it == m_attachedEffects.end())
return nullptr;

return *it;
}

void AttachableObject::drawAttachedEffect(const Point& dest, LightView* lightView, bool isOnTop, AttachedEffectDrawPlace drawPlace)
{
for (const auto& effect : m_attachedEffects) {
if (effect->getDrawPlace() != drawPlace)
continue;

effect->draw(dest, isOnTop, lightView);
if (effect->getLoop() == 0) {
g_dispatcher.addEvent([self = std::static_pointer_cast<AttachableObject>(shared_from_this()), effectId = effect->getId()]() {
self->detachEffectById(effectId);
});
}
}
}
52 changes: 52 additions & 0 deletions src/client/attachableobject.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2010-2022 OTClient <https://github.com/edubart/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.
*/

#pragma once
#include "attachedeffect.h"

// @bindclass
#pragma pack(push,1) // disable memory alignment
class AttachableObject : public LuaObject
{
public:
void attachEffect(const AttachedEffectPtr& obj);
void clearAttachedEffects();
bool detachEffectById(uint16_t id);
AttachedEffectPtr getAttachedEffectById(uint16_t id);

virtual LuaObjectPtr attachedObjectToLuaObject() = 0;
virtual void onStartAttachEffect(const AttachedEffectPtr& effect) { };
virtual void onDispatcherAttachEffect(const AttachedEffectPtr& effect) { };
virtual void onStartDetachEffect(const AttachedEffectPtr& effect) { };

bool isOwnerHidden() { return m_ownerHidden > 0; }

const std::vector<AttachedEffectPtr>& getAttachedEffects() { return m_attachedEffects; };

protected:
void drawAttachedEffect(const Point& dest, LightView* lightView, bool isOnTop, AttachedEffectDrawPlace drawPlace = AttachedEffectDrawPlace::DEFAULT);
void onDetachEffect(const AttachedEffectPtr& effect);

std::vector<AttachedEffectPtr> m_attachedEffects;
uint8_t m_ownerHidden{ 0 };
};
#pragma pack(pop)
14 changes: 14 additions & 0 deletions src/client/attachedeffect.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@
#include "thingtype.h"
#include "outfit.h"

enum class AttachedEffectDrawPlace : uint8_t
{
DEFAULT,
BEFORE_GROUND,
BEFORE_ITEM,
BEFORE_CREATURE,
BEFORE_EFFECTS,
LAST,
};

class AttachedEffect : public LuaObject
{
public:
Expand Down Expand Up @@ -72,6 +82,9 @@ class AttachedEffect : public LuaObject

void attachEffect(const AttachedEffectPtr& e) { m_effects.emplace_back(e); }

AttachedEffectDrawPlace getDrawPlace() { return m_drawPlace; }
void setDrawPlace(AttachedEffectDrawPlace drawPlace) { m_drawPlace = drawPlace; }

private:
int getCurrentAnimationPhase();

Expand All @@ -86,6 +99,7 @@ class AttachedEffect : public LuaObject
uint8_t m_speed{ 100 };
uint8_t m_opacity{ 100 };
uint8_t m_lastAnimation{ 0 };
AttachedEffectDrawPlace m_drawPlace{ AttachedEffectDrawPlace::DEFAULT };

uint16_t m_id{ 0 };
uint16_t m_duration{ 0 };
Expand Down
18 changes: 11 additions & 7 deletions src/client/luafunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#include "uiminimap.h"
#include "uiprogressrect.h"
#include "uisprite.h"
#include "attachableobject.h"

#ifdef FRAMEWORK_EDITOR
#include "houses.h"
Expand Down Expand Up @@ -391,7 +392,14 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<Container>("getSize", &Container::getSize);
g_lua.bindClassMemberFunction<Container>("getFirstIndex", &Container::getFirstIndex);

g_lua.registerClass<Thing>();
g_lua.registerClass<AttachableObject>();
g_lua.bindClassMemberFunction<AttachableObject>("getAttachedEffects", &AttachableObject::getAttachedEffects);
g_lua.bindClassMemberFunction<AttachableObject>("attachEffect", &AttachableObject::attachEffect);
g_lua.bindClassMemberFunction<AttachableObject>("detachEffectById", &AttachableObject::detachEffectById);
g_lua.bindClassMemberFunction<AttachableObject>("getAttachedEffectById", &AttachableObject::getAttachedEffectById);
g_lua.bindClassMemberFunction<AttachableObject>("clearAttachedEffects", &AttachableObject::clearAttachedEffects);

g_lua.registerClass<Thing, AttachableObject>();
g_lua.bindClassMemberFunction<Thing>("setId", &Thing::setId);
g_lua.bindClassMemberFunction<Thing>("setShader", &Thing::setShader);
g_lua.bindClassMemberFunction<Thing>("setPosition", &Thing::setPosition);
Expand Down Expand Up @@ -434,11 +442,6 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<Thing>("isTopEffect", &Thing::isTopEffect);
g_lua.bindClassMemberFunction<Thing>("isLyingCorpse", &Thing::isLyingCorpse);
g_lua.bindClassMemberFunction<Thing>("getDefaultAction", &Thing::getDefaultAction);
g_lua.bindClassMemberFunction<Thing>("getAttachedEffects", &Thing::getAttachedEffects);
g_lua.bindClassMemberFunction<Thing>("attachEffect", &Thing::attachEffect);
g_lua.bindClassMemberFunction<Thing>("detachEffectById", &Thing::detachEffectById);
g_lua.bindClassMemberFunction<Thing>("getAttachedEffectById", &Thing::getAttachedEffectById);
g_lua.bindClassMemberFunction<Thing>("clearAttachedEffects", &Thing::clearAttachedEffects);
g_lua.bindClassMemberFunction<Thing>("getClassification", &Thing::getClassification);

#ifdef FRAMEWORK_EDITOR
Expand Down Expand Up @@ -690,6 +693,7 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<AttachedEffect>("canDrawOnUI", &AttachedEffect::canDrawOnUI);
g_lua.bindClassMemberFunction<AttachedEffect>("setCanDrawOnUI", &AttachedEffect::setCanDrawOnUI);
g_lua.bindClassMemberFunction<AttachedEffect>("attachEffect", &AttachedEffect::attachEffect);
g_lua.bindClassMemberFunction<AttachedEffect>("setDrawPlace", &AttachedEffect::setDrawPlace);

g_lua.registerClass<StaticText>();
g_lua.bindClassStaticFunction<StaticText>("create", [] { return std::make_shared<StaticText>(); });
Expand Down Expand Up @@ -756,7 +760,7 @@ void Client::registerLuaFunctions()
g_lua.bindClassMemberFunction<LocalPlayer>("setResourceBalance", &LocalPlayer::setResourceBalance);
g_lua.bindClassMemberFunction<LocalPlayer>("getTotalMoney", &LocalPlayer::getTotalMoney);

g_lua.registerClass<Tile>();
g_lua.registerClass<Tile, AttachableObject>();
g_lua.bindClassMemberFunction<Tile>("clean", &Tile::clean);
g_lua.bindClassMemberFunction<Tile>("addThing", &Tile::addThing);
g_lua.bindClassMemberFunction<Tile>("getThing", &Tile::getThing);
Expand Down
Loading

0 comments on commit ee322f7

Please sign in to comment.