From 894cb5d09572bcf9d8872e1f5ef073e5c36f18be Mon Sep 17 00:00:00 2001 From: TracentEden <92269743+TracentEden@users.noreply.github.com> Date: Thu, 9 May 2024 03:06:01 +0300 Subject: [PATCH] Fix exp ring recharge cost logic Co-authored-by: paladindamarus --- scripts/globals/conquest.lua | 51 +++++++++++++++++++++++++++--------- src/map/lua/lua_item.cpp | 11 ++++++++ src/map/lua/lua_item.h | 2 ++ 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/scripts/globals/conquest.lua b/scripts/globals/conquest.lua index 5e48e516e14..416b62d7b80 100644 --- a/scripts/globals/conquest.lua +++ b/scripts/globals/conquest.lua @@ -571,9 +571,9 @@ local crystals = local expRings = { - [xi.item.CHARIOT_BAND] = { cp = 350, charges = 7 }, - [xi.item.EMPRESS_BAND] = { cp = 700, charges = 7 }, - [xi.item.EMPEROR_BAND] = { cp = 600, charges = 3 }, + [xi.item.CHARIOT_BAND] = { chargesWhenFull = 7, costPerCharge = 50 }, + [xi.item.EMPRESS_BAND] = { chargesWhenFull = 7, costPerCharge = 100 }, + [xi.item.EMPEROR_BAND] = { chargesWhenFull = 3, costPerCharge = 200 }, } local function conquestRanking() @@ -1123,25 +1123,50 @@ xi.conquest.overseerOnTrade = function(player, npc, trade, guardNation, guardTyp -- RECHARGE EXP RING if not tradeConfirmed and expRings[item] and npcUtil.tradeHas(trade, item) then - -- TODO: Can you recharge a full ring? This case would need to be handled. if xi.settings.main.BYPASS_EXP_RING_ONE_PER_WEEK == 1 or player:getCharVar('CONQUEST_RING_RECHARGE') == 0 then local ring = expRings[item] - if player:getCP() >= ring.cp then - player:delCP(ring.cp) - player:confirmTrade() - player:addItem(item) - player:setCharVar('CONQUEST_RING_RECHARGE', 1, NextConquestTally()) - player:showText(npc, mOffset + 58, item, ring.cp, ring.charges) -- 'Your ring is now fully recharged.' + -- find the item so can determine the actual charges used + -- (if still some charges left then recharging is proportionally less CP) + local ringItem = player:findItem(item) + if ringItem then + -- by default assume all charges used and calculate CP cost for a full recharge + local cpCost = ring.chargesWhenFull * ring.costPerCharge + + -- calculate the charges used (clamp to ensure no strangeness) + local chargesLeft = utils.clamp(ringItem:getCurrentCharges(), 0, ring.chargesWhenFull) + local chargesUsed = ring.chargesWhenFull - chargesLeft + + -- player trying to recharge a full ring so notify player and exit + if chargesUsed == 0 then + player:showText(npc, mOffset + 57, item) -- 'The is already fully charged.' + return + -- player has used some but not all charges so calculate the CP cost for recharge + elseif + chargesUsed > 0 and + chargesUsed < ring.chargesWhenFull + then + cpCost = chargesUsed * ring.costPerCharge + end + + -- if enough CP then perform the recharge + if player:getCP() >= cpCost then + player:delCP(cpCost) + player:confirmTrade() + player:addItem(item) + player:setCharVar('CONQUEST_RING_RECHARGE', 1, NextConquestTally()) + player:showText(npc, mOffset + 58, item, cpCost, chargesUsed) -- 'Your ring is now fully recharged.' + else + player:showText(npc, mOffset + 55, item, cpCost) -- 'You do not have the required conquest points to recharge.' + end + -- could not find the player's current ring so stop attempt else - player:showText(npc, mOffset + 55, item, ring.cp) -- 'You do not have the required conquest points to recharge.' + return end else - -- TODO: Verify that message is retail correct. - -- This gives feedback on a failure at least, and is grouped with the recharge messages. Confident enough for a commit. player:showText(npc, mOffset + 56, item) -- 'Please be aware that you can only purchase or recharge once during the period between each conquest results tally. end end diff --git a/src/map/lua/lua_item.cpp b/src/map/lua/lua_item.cpp index ee27229651c..0d2f17f2fcf 100644 --- a/src/map/lua/lua_item.cpp +++ b/src/map/lua/lua_item.cpp @@ -252,6 +252,16 @@ auto CLuaItem::getSignature() -> std::string return signature; } +uint8 CLuaItem::getCurrentCharges() +{ + if (auto* PUsableItem = dynamic_cast(m_PLuaItem)) + { + return PUsableItem->getCurrentCharges(); + } + + return 0; +} + uint8 CLuaItem::getAppraisalID() { return m_PLuaItem->m_extra[0x16]; @@ -353,6 +363,7 @@ void CLuaItem::Register() SOL_REGISTER("getSignature", CLuaItem::getSignature); SOL_REGISTER("getAppraisalID", CLuaItem::getAppraisalID); SOL_REGISTER("setAppraisalID", CLuaItem::setAppraisalID); + SOL_REGISTER("getCurrentCharges", CLuaItem::getCurrentCharges); SOL_REGISTER("isInstalled", CLuaItem::isInstalled); SOL_REGISTER("setSoulPlateData", CLuaItem::setSoulPlateData); SOL_REGISTER("getSoulPlateData", CLuaItem::getSoulPlateData); diff --git a/src/map/lua/lua_item.h b/src/map/lua/lua_item.h index 483bbe942bf..7891b977b4f 100644 --- a/src/map/lua/lua_item.h +++ b/src/map/lua/lua_item.h @@ -84,6 +84,8 @@ class CLuaItem uint8 getAppraisalID(); // get an appraisal ID void setAppraisalID(uint8 id); // set an appraisal ID + uint8 getCurrentCharges(); // Get remaining charges + bool isInstalled(); void setSoulPlateData(std::string const& name, uint16 mobFamily, uint8 zeni, uint16 skillIndex, uint8 fp);