Hello – I still have a problem with the manarune...
I don’t know what else to say – my goal is simple: I want to be able to use rune SD (spells) and UH/manarune (actions) at the same time. The code I have works almost perfectly, but there’s one problem — when I press the hotkey for the manarune twice very quickly, it heals me twice in a very short time.
It’s like it heals twice per second, even though I’ve set the exhaust to 1 second.
This is the bug I really want to fix — I’d even be willing to pay for help with it.
It really matters to me because I just can’t figure it out myself.
my function action.cppC:
manarune:
my config.lua
Best regards.
I don’t know what else to say – my goal is simple: I want to be able to use rune SD (spells) and UH/manarune (actions) at the same time. The code I have works almost perfectly, but there’s one problem — when I press the hotkey for the manarune twice very quickly, it heals me twice in a very short time.
It’s like it heals twice per second, even though I’ve set the exhaust to 1 second.
This is the bug I really want to fix — I’d even be willing to pay for help with it.
It really matters to me because I just can’t figure it out myself.
my function action.cppC:
C++:
bool Actions::useItemEx(Player* player, const Position& fromPos, const Position& toPos,
uint8_t toStackPos, Item* item, bool isHotkey, Creature* creature/* = nullptr*/)
{
// Mikro-delay dla mana-run (żeby zabić dwuklik), normalny delay dla reszty
static constexpr uint16_t MANA_RUNE_IDS[] = { 2270, 2272 }; // dopisz tu inne ID jeśli masz
const uint16_t id = item->getID();
const bool isManaRune = std::find(std::begin(MANA_RUNE_IDS), std::end(MANA_RUNE_IDS), id) != std::end(MANA_RUNE_IDS);
if (isManaRune) {
// minimalny exhaust na poziomie C++, wystarczy by zablokować 2 pakiety „pod rząd”
player->setNextAction(OTSYS_TIME() + 50); // 50 ms
}
else {
player->setNextAction(OTSYS_TIME() + g_config.getNumber(ConfigManager::EX_ACTIONS_DELAY_INTERVAL));
}
player->stopWalk();
Action* action = getAction(item);
if (!action) {
player->sendCancelMessage(RETURNVALUE_CANNOTUSETHISOBJECT);
return false;
}
ReturnValue ret = action->canExecuteAction(player, toPos);
if (ret != RETURNVALUE_NOERROR) {
player->sendCancelMessage(ret);
return false;
}
if (isHotkey) {
showUseHotkeyMessage(player, item, player->getItemTypeCount(item->getID(), -1));
}
if (!action->executeUse(player, item, fromPos, action->getTarget(player, creature, toPos, toStackPos), toPos, isHotkey)) {
if (!action->hasOwnErrorHandler()) {
player->sendCancelMessage(RETURNVALUE_CANNOTUSETHISOBJECT);
}
return false;
}
return true;
}
manarune:
LUA:
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
-- tylko na graczy
if not target or not target:isPlayer() then
return true
end
-- akceptowane ID runy (dopasuj do swoich)
local itemId = item:getId()
if itemId ~= 2270 and itemId ~= 2272 then
return false
end
-- EXHAUST: najpierw sprawdź, jeśli jest - przerwij
if player:getExhaustion(54328) > 0 then
player:sendTextMessage(MESSAGE_STATUS_SMALL, Game.getReturnMessage(RETURNVALUE_YOUAREEXHAUSTED))
player:getPosition():sendMagicEffect(CONST_ME_POFF)
return false
end
-- USTAW EXHAUST OD RAZU (np. 1s)
player:setExhaustion(54328, 1)
-- obliczenia
local min, max = 0, 0
local minHp, maxHp = 0, 0
local function safeBonus(pl)
local b1 = getPlayerStorageValue(pl, 2001) or 0
if b1 < 0 then b1 = 0 end
local b2 = getPlayerStatsAttribute(pl, "bonushealing") or 0
return (b1 or 0) + (b2 or 0)
end
-- funkcja progów leczenia many jak potki z RL
local function getStaticManaRange(pl)
local level = pl:getLevel()
local voc = getPlayerVocation(pl)
-- domyślnie: mana potion (dla wszystkich)
local minM, maxM = 70, 130
-- strong mana potion od 50 lvla (ED/MS/RP)
if level >= 50 and (voc == 1 or voc == 2 or voc == 3 or voc == 5 or voc == 6 or voc == 7) then
minM, maxM = 110, 190
end
-- great mana potion od 80 lvla (ED/MS)
if level >= 80 and (voc == 1 or voc == 2 or voc == 5 or voc == 6) then
minM, maxM = 200, 300
end
return minM, maxM
end
local voc = getPlayerVocation(target)
if voc == 1 or voc == 2 or voc == 5 or voc == 6 then -- ED / MS
local minn = (target:getMaxMana() / 100) * 66.5
local maxx = (target:getMaxMana() / 100) * 66.5
local bonus = safeBonus(target)
local flatBonus = (getPlayerStorageValue(player, 90001) > 0 and getPlayerStorageValue(player, 90001) or 0)
min = minn + (minn / 100 * bonus) + flatBonus
max = maxx + (maxx / 100 * bonus) + flatBonus
elseif voc == 3 or voc == 7 then -- RP
local minn = (target:getMaxMana() / 100) * 66.5
local maxx = (target:getMaxMana() / 100) * 66.5
local bonus = safeBonus(target)
local flatBonus = (getPlayerStorageValue(player, 90001) > 0 and getPlayerStorageValue(player, 90001) or 0)
min = minn + (minn / 100 * bonus) + flatBonus
max = maxx + (maxx / 100 * bonus) + flatBonus
local minnHp = (target:getMaxHealth() / 100) * 66.80
local maxxHp = (target:getMaxHealth() / 100) * 66.30
local bonusHp = safeBonus(target)
local flatBonus = (getPlayerStorageValue(player, 90001) > 0 and getPlayerStorageValue(player, 90001) or 0)
minHp = -(minnHp + (minnHp / 100 * bonusHp)) + flatBonus
maxHp = -(maxxHp + (maxxHp / 100 * bonusHp)) + flatBonus
elseif voc == 4 or voc == 8 then -- EK
local minn = (target:getMaxMana() / 100) * 66.8
local maxx = (target:getMaxMana() / 100) * 66.0
local bonus = safeBonus(target)
local flatBonus = (getPlayerStorageValue(player, 90001) > 0 and getPlayerStorageValue(player, 90001) or 0)
min = minn + (minn / 100 * bonus) + flatBonus
max = maxx + (maxx / 100 * bonus) + flatBonus
end
-- teraz sprawdzamy progi z potków
local staticMin, staticMax = getStaticManaRange(target)
local bonus = safeBonus(target)
local flatBonus = (getPlayerStorageValue(player, 90001) > 0 and getPlayerStorageValue(player, 90001) or 0)
-- dodajemy bonusy do wartości z potków
staticMin = staticMin + (staticMin / 100 * bonus) + flatBonus
staticMax = staticMax + (staticMax / 100 * bonus) + flatBonus
-- jeśli obliczony % heal jest mniejszy niż próg, użyj progu
if min < staticMin then
min = staticMin
end
if max < staticMax then
max = staticMax
end
-- leczenie/doładowanie many
if target == player then
if voc == 3 or voc == 7 then
-- Jeśli chcesz, możesz włączyć również leczenie HP dla RP:
-- doTargetCombatHealth(0, target, COMBAT_HEALING, minHp, maxHp, CONST_ME_MAGIC_BLUE)
end
doTargetCombatMana(0, target, min, max, CONST_ME_MAGIC_BLUE)
else
-- na innych: połowa efektu
if not doTargetCombatMana(0, target, min / 2, max / 2, CONST_ME_MAGIC_BLUE) then
return false
end
end
-- liczniki/achievementy
local cnt = getPlayerStorageValue(target, 3766)
if cnt < 0 then cnt = 0 end
cnt = cnt + 1
setPlayerStorageValue(target, 3766, cnt)
if cnt == 6999 then
doPlayerAddAchievement(Player(target), 41)
end
target:say("Aaaah...", TALKTYPE_MONSTER_SAY)
-- zużycie ładunku
if getConfigInfo('removeChargesFromRunes') == true then
item:remove(1)
end
return true
end
my config.lua
LUA:
timeBetweenActions = 200
timeBetweenExActions = 1000
Best regards.