diff --git a/scripts/globals/roe.lua b/scripts/globals/roe.lua index b1a887d7fab..542249cbe77 100644 --- a/scripts/globals/roe.lua +++ b/scripts/globals/roe.lua @@ -68,8 +68,10 @@ end local defaults = { check = checks.masterCheck, -- Check function should return true/false increment = 1, -- Amount to increment per successful check + notify = 1, -- Progress notifications shown every X increases goal = 1, -- Progress goal reqs = {}, -- Other requirements. List of function names from above, with required values. + reward = {}, -- Reward parameters give on completion. (See completeRecord directly below.) } --[[ ************************************************************************** @@ -282,6 +284,7 @@ tpz.roe.records = trigger = triggers.dmgDealt, goal = 100000, increment = 0, + notify = 5000, reward = { sparks = 1000, xp = 5000 , item = { 6181 } }, check = function(self, player, params) if params.dmg and params.dmg > 0 then diff --git a/src/map/lua/lua_baseentity.cpp b/src/map/lua/lua_baseentity.cpp index ed86c2c94b6..2f9f930da4c 100644 --- a/src/map/lua/lua_baseentity.cpp +++ b/src/map/lua/lua_baseentity.cpp @@ -2394,7 +2394,7 @@ inline int32 CLuaBaseEntity::sendGuild(lua_State* L) GUILDSTATUS status = GUILD_OPEN; - /* + /* * No more guild holidays since 2014 if (VanadielDay == holiday) { @@ -6926,12 +6926,21 @@ inline int32 CLuaBaseEntity::setEminenceProgress(lua_State *L) CCharEntity* PChar = (CCharEntity*)m_PBaseEntity; uint16 recordID = static_cast(lua_tointeger(L, 1)); uint32 progress = static_cast(lua_tointeger(L, 2)); + uint32 total = static_cast(lua_tointeger(L, 3)); + + // Determine threshold for sending progress messages + bool progressNotify {true}; + if (uint32 threshold = roeutils::RoeCache.NotifyThresholds[recordID]; threshold > 1) + { + uint32 prevStep = static_cast(roeutils::GetEminenceRecordProgress(PChar, recordID) / threshold); + uint32 nextStep = static_cast(progress / threshold); + progressNotify = nextStep > prevStep; + } bool result = roeutils::SetEminenceRecordProgress(PChar, recordID, progress); lua_pushboolean(L, result); - uint32 total = static_cast(lua_tointeger(L, 3)); - if (total) + if (total && progressNotify) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, recordID, 0, MSGBASIC_ROE_RECORD)); PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, progress, total, MSGBASIC_ROE_PROGRESS)); diff --git a/src/map/roe.cpp b/src/map/roe.cpp index 49f53cd98d7..398b3dcab2a 100644 --- a/src/map/roe.cpp +++ b/src/map/roe.cpp @@ -33,7 +33,7 @@ #include "packets/roe_update.h" std::array RoeHandlers; -RoeCache roeutils::RoeBitmaps; +RoeSystemData roeutils::RoeCache; namespace roeutils { @@ -84,8 +84,9 @@ int32 RegisterHandler(lua_State* L) int32 ParseRecords(lua_State* L) { - roeutils::RoeBitmaps.ImplementedRecords.reset(); - roeutils::RoeBitmaps.RepeatableRecords.reset(); + roeutils::RoeCache.ImplementedRecords.reset(); + roeutils::RoeCache.RepeatableRecords.reset(); + roeutils::RoeCache.NotifyThresholds.fill(1); if (lua_isnil(L, -1) || !lua_istable(L, -1)) return 0; @@ -96,7 +97,13 @@ int32 ParseRecords(lua_State* L) { // Set Implemented bit. uint32 recordID = static_cast(lua_tointeger(L, -2)); - roeutils::RoeBitmaps.ImplementedRecords.set(recordID); + roeutils::RoeCache.ImplementedRecords.set(recordID); + + // Set notification threshold + lua_getfield(L, -1, "notify"); + if (!lua_isnil(L, -1)) + roeutils::RoeCache.NotifyThresholds[recordID] = static_cast((lua_tointeger(L, -1))); + lua_pop(L, 1); // Set repeatability bit lua_getfield(L, -1, "reward"); @@ -105,7 +112,7 @@ int32 ParseRecords(lua_State* L) lua_getfield(L, -1, "repeatable"); if (lua_toboolean(L, -1)) { - roeutils::RoeBitmaps.RepeatableRecords.set(recordID); + roeutils::RoeCache.RepeatableRecords.set(recordID); } lua_pop(L, 1); } @@ -129,6 +136,7 @@ bool event(ROE_EVENT eventID, CCharEntity* PChar, RoeDatagramList payload) return 0; lua_State* L = luautils::LuaHandle; + uint32 stackTop = lua_gettop(L); lua_getglobal(L, "tpz"); lua_getfield(L, -1, "roe"); @@ -183,6 +191,7 @@ bool event(ROE_EVENT eventID, CCharEntity* PChar, RoeDatagramList payload) } } } + lua_settop(L, stackTop); return true; } @@ -198,7 +207,7 @@ bool event(ROE_EVENT eventID, CCharEntity* PChar) // shorthand for no-datagram c void SetEminenceRecordCompletion(CCharEntity* PChar, uint16 recordID, bool newStatus) { - uint8 page = recordID / 8; + uint16 page = recordID / 8; uint8 bit = recordID % 8; if (newStatus) PChar->m_eminenceLog.complete[page] |= (1 << bit); @@ -214,24 +223,16 @@ void SetEminenceRecordCompletion(CCharEntity* PChar, uint16 recordID, bool newSt bool GetEminenceRecordCompletion(CCharEntity* PChar, uint16 recordID) { - uint8 page = recordID / 8; + uint16 page = recordID / 8; uint8 bit = recordID % 8; return PChar->m_eminenceLog.complete[page] & (1 << bit); } bool AddEminenceRecord(CCharEntity* PChar, uint16 recordID) { - // TODO: Time limited records aren't implemented yet and can't be accepted normally. - // For now we are refusing their IDs outright and protecting its slot from use here. - if (recordID > 2047) - { - std::string message = "Special Event/Timed Records can not be taken."; - PChar->pushPacket(new CChatMessagePacket(PChar, MESSAGE_NS_SAY, message, "RoE System")); - return false; - } // We deny taking records which aren't implemented in the Lua - if (!roeutils::RoeBitmaps.ImplementedRecords.test(recordID)) + if (!roeutils::RoeCache.ImplementedRecords.test(recordID)) { std::string message = "The record #" + std::to_string(recordID) + " is not implemented at this time."; PChar->pushPacket(new CChatMessagePacket(PChar, MESSAGE_NS_SAY, message, "RoE System")); @@ -239,7 +240,7 @@ bool AddEminenceRecord(CCharEntity* PChar, uint16 recordID) } // Prevent packet-injection for re-taking completed records which aren't marked repeatable. - if (roeutils::GetEminenceRecordCompletion(PChar, recordID) && !roeutils::RoeBitmaps.RepeatableRecords.test(recordID)) + if (roeutils::GetEminenceRecordCompletion(PChar, recordID) && !roeutils::RoeCache.RepeatableRecords.test(recordID)) return false; // Per above, this i < 30 is correct. diff --git a/src/map/roe.h b/src/map/roe.h index f02b8e9bfe9..9f11286ca59 100644 --- a/src/map/roe.h +++ b/src/map/roe.h @@ -50,10 +50,11 @@ enum ROE_EVENT ROE_NONE // End of enum marker and OOB checkpost. Do not move or remove, place any new types above. }; -struct RoeCache +struct RoeSystemData { std::bitset<4096> ImplementedRecords; std::bitset<4096> RepeatableRecords; + std::array NotifyThresholds; }; struct RoeCheckHandler @@ -79,16 +80,14 @@ struct RoeDatagram CItem* item; } data; - RoeDatagram(std::string param, uint32 id) + RoeDatagram(std::string param, uint32 id) : param{param} { this->type = RoeDatagramPayload::uinteger; - this->param = param; this->data.uinteger = id; } - RoeDatagram(std::string param, CMobEntity* PMob) + RoeDatagram(std::string param, CMobEntity* PMob) : param{param} { this->type = RoeDatagramPayload::mob; - this->param = param; this->data.mobEntity = PMob; } }; @@ -97,7 +96,7 @@ typedef std::vector RoeDatagramList; namespace roeutils { -extern RoeCache RoeBitmaps; +extern RoeSystemData RoeCache; void init(); int32 RegisterHandler(lua_State* L); diff --git a/win32/vcxproj/topaz_game.vcxproj b/win32/vcxproj/topaz_game.vcxproj index a9f2a39b2fa..6af7a3e291f 100644 --- a/win32/vcxproj/topaz_game.vcxproj +++ b/win32/vcxproj/topaz_game.vcxproj @@ -417,6 +417,9 @@ + + + @@ -438,6 +441,7 @@ + @@ -700,7 +704,6 @@ - diff --git a/win32/vcxproj/topaz_game.vcxproj.filters b/win32/vcxproj/topaz_game.vcxproj.filters index 2bfd5eb0f9f..cab2a98d95e 100644 --- a/win32/vcxproj/topaz_game.vcxproj.filters +++ b/win32/vcxproj/topaz_game.vcxproj.filters @@ -419,6 +419,15 @@ Header Files\packets + + Header Files\packets + + + Header Files\packets + + + Header Files\packets + Header Files\packets @@ -1213,6 +1222,15 @@ Source Files\packets + + Header Files\packets + + + Header Files\packets + + + Header Files\packets + Source Files\packets