oen432
Legendary OT User
This month I wanted to start sharing source changes for TFS and OTClient. There are plenty of stuff coming so I'll start with smaller ones.
Simple and straight forward. Progressbar can be used to show something about to happen (spell is about to be cast) or about to end (like a buff).
Progress is shown under creature HP/MP bar. Works for players and monsters so it can be used in many ways. New Lua methods and events included.
Installation is for advanced users and I don't take responsibility for damage caused by wrongly added code.
TFS-side you can use it inside Lua scripts.
Creature can be Player or Monster.
OTClient-side you can check if progressbar started or is being updated. This can be used for all sort of different things (like in video above)
Feedback is very welcome!
Progressbar
Simple and straight forward. Progressbar can be used to show something about to happen (spell is about to be cast) or about to end (like a buff).
Progress is shown under creature HP/MP bar. Works for players and monsters so it can be used in many ways. New Lua methods and events included.
Installation is for advanced users and I don't take responsibility for damage caused by wrongly added code.
Installation
First we start with TFS.- Open
const.h
and addC++:#define PROGRESSBAR
- Open
game.h
and addC++:#ifdef PROGRESSBAR void startProgressbar(Creature* creature, uint32_t duration, bool ltr = true); #endif
- Open
game.cpp
and addC++:#ifdef PROGRESSBAR void Game::startProgressbar(Creature* creature, uint32_t duration, bool ltr) { SpectatorHashSet spectators; map.getSpectators(spectators, creature->getPosition(), false, true); for (Creature* spectator : spectators) { if (Player* tmpPlayer = spectator->getPlayer()) { tmpPlayer->sendProgressbar(creature->getID(), duration, ltr); } } } #endif
- Open
luascript.h
and addC++:#ifdef PROGRESSBAR static int luaCreatureSetProgressbar(lua_State* L); #endif
- Open
luascript.cpp
and add insideregisterFunctions
C++:#ifdef PROGRESSBAR registerMethod("Creature", "sendProgressbar", LuaScriptInterface::luaCreatureSetProgressbar); #endif
- At the bottom add
C++:
#ifdef PROGRESSBAR int LuaScriptInterface::luaCreatureSetProgressbar(lua_State* L) { // creature:sendProgressbar(duration, leftToRight) Creature* creature = getUserdata<Creature>(L, 1); uint32_t duration = getNumber<uint32_t>(L, 2); bool ltr = getBoolean(L, 3); if (creature) { g_game.startProgressbar(creature, duration, ltr); pushBoolean(L, true); } else { lua_pushnil(L); } return 1; } #endif
- Open
player.h
and add undersendNetworkMessage
C++:#ifdef PROGRESSBAR void sendProgressbar(uint32_t id, uint32_t duration, bool ltr = true) { if (client) { client->sendProgressbar(id, duration, ltr); } } #endif
- Open
protocolgame.h
and addC++:#ifdef PROGRESSBAR void sendProgressbar(uint32_t id, uint32_t duration, bool ltr = true); #endif
- Open
protocolgame.cpp
and addC++:#ifdef PROGRESSBAR void ProtocolGame::sendProgressbar(uint32_t id, uint32_t duration, bool ltr) { NetworkMessage msg; msg.addByte(0x3b); msg.add<uint32_t>(id); msg.add<uint32_t>(duration); msg.addByte(ltr); writeToOutputBuffer(msg); } #endif
- Open
const.h
and addC++:#define PROGRESSBAR
- Open
protocolcodes.h
and underGameServerChangeMapAwareRange = 51,
addC++:#ifdef PROGRESSBAR ServerRunProgressbar = 59, #endif
- Open
protocolgame.h
and addC++:#ifdef PROGRESSBAR void parseProgressbar(const InputMessagePtr& msg); #endif
- Open
protocolgameparse.cpp
and underProto::GameServerChangeMapAwareRange:
afterbreak;
addC++:#ifdef PROGRESSBAR case Proto::ServerRunProgressbar: parseProgressbar(msg); break; #endif
- At the bottom add
C++:
#ifdef PROGRESSBAR void ProtocolGame::parseProgressbar(const InputMessagePtr& msg) { uint32 id = msg->getU32(); uint32 duration = msg->getU32(); bool ltr = msg->getU8(); CreaturePtr creature = g_map.getCreatureById(id); if (creature) creature->setProgressbar(duration, ltr); else g_logger.traceError(stdext::format("could not get creature with id %d", id)); } #endif
- Open
creature.h
and addC++:#ifdef PROGRESSBAR uint8 getProgressbarPercent() { return m_progressbarPercent; } void setProgressbar(uint32 duration, bool ltr); void updateProgressbar(uint32 duration, bool ltr); #endif
- Under
uint8 m_healthPercent;
addC++:#ifdef PROGRESSBAR uint8 m_progressbarPercent; ScheduledEventPtr m_progressbarUpdateEvent; Timer m_progressbarTimer; #endif
- Open
creature.cpp
and insideCreature::Creature() : Thing()
addC++:#ifdef PROGRESSBAR m_progressbarPercent = 0; m_progressbarUpdateEvent = nullptr; #endif
- Under
if(drawFlags & Otc::DrawManaBar && isLocalPlayer()) {
(under last closing bracket of thatif
) addC++:#ifdef PROGRESSBAR if (getProgressbarPercent()) { backgroundRect.moveTop(backgroundRect.bottom()); g_painter->setColor(Color::black); g_painter->drawFilledRect(backgroundRect); Rect progressbarRect = backgroundRect.expanded(-1); double maxBar = 100; progressbarRect.setWidth(getProgressbarPercent() / (maxBar * 1.0) * 25); g_painter->setColor(Color::white); g_painter->drawFilledRect(progressbarRect); } #endif
- Somewhere at the bottom add
C++:
#ifdef PROGRESSBAR void Creature::setProgressbar(uint32 duration, bool ltr) { if (m_progressbarUpdateEvent) { m_progressbarUpdateEvent->cancel(); m_progressbarUpdateEvent = nullptr; } if (duration > 0) { m_progressbarTimer.restart(); updateProgressbar(duration, ltr); } else m_progressbarPercent = 0; callLuaField("onProgressbarStart", duration, ltr); } void Creature::updateProgressbar(uint32 duration, bool ltr) { if (m_progressbarTimer.ticksElapsed() < duration) { if(ltr) m_progressbarPercent = abs(m_progressbarTimer.ticksElapsed() / static_cast<double>(duration) * 100); else m_progressbarPercent = abs((m_progressbarTimer.ticksElapsed() / static_cast<double>(duration) * 100) - 100); auto self = static_self_cast<Creature>(); m_progressbarUpdateEvent = g_dispatcher.scheduleEvent([=] { self->updateProgressbar(duration, ltr); }, 50); } else { m_progressbarPercent = 0; } callLuaField("onProgressbarUpdate", m_progressbarPercent, duration, ltr); } #endif
Usage
TFS-side you can use it inside Lua scripts.
Lua:
creature:sendProgressbar(duration, ltr)
duration
- in ms, how long should it take to fill or empty the barltr
- true if bar should fill from left to right, false if should empty from right to leftCreature can be Player or Monster.
OTClient-side you can check if progressbar started or is being updated. This can be used for all sort of different things (like in video above)
Lua:
connect(
Creature,
{
onProgressbarStart = onProgressbarStart,
onProgressbarUpdate = onProgressbarUpdate
}
)
function onProgressbarStart(creature, duration, ltr)
-- Code
end
function onProgressbarUpdate(creature, percent, duration, ltr)
-- Code
end
Feedback is very welcome!
Last edited: