From 718d9d39bc078d55a7968a1b7460473afa471b92 Mon Sep 17 00:00:00 2001 From: codinablack Date: Fri, 6 Dec 2024 16:07:10 -0600 Subject: [PATCH] Fixes issue #16 - Code imported on this commit is take from TFS and is therefore under the same license as TFS, GPL. It's an exclusion from other code added by myself for being under the new license, MIT. --- data/events/scripts/player.lua | 35 -- .../player/default_onGainExperience.lua | 95 ++++++ .../player/default_onLookInMarket.lua | 311 ++++++++++++++++++ .../player/default_onLookInShop.lua | 25 ++ .../player/default_onRotateItem.lua | 10 + .../player/default_onSpellTry.lua | 7 + 6 files changed, 448 insertions(+), 35 deletions(-) create mode 100644 data/scripts/eventcallbacks/player/default_onGainExperience.lua create mode 100644 data/scripts/eventcallbacks/player/default_onLookInMarket.lua create mode 100644 data/scripts/eventcallbacks/player/default_onLookInShop.lua create mode 100644 data/scripts/eventcallbacks/player/default_onRotateItem.lua create mode 100644 data/scripts/eventcallbacks/player/default_onSpellTry.lua diff --git a/data/events/scripts/player.lua b/data/events/scripts/player.lua index d6842552..9cc52653 100644 --- a/data/events/scripts/player.lua +++ b/data/events/scripts/player.lua @@ -130,41 +130,6 @@ function Player:onTradeCompleted(target, item, targetItem, isSuccess) end end -local soulCondition = Condition(CONDITION_SOUL, CONDITIONID_DEFAULT) -soulCondition:setTicks(4 * 60 * 1000) -soulCondition:setParameter(CONDITION_PARAM_SOULGAIN, 1) - -local function useStamina(player) - local staminaMinutes = player:getStamina() - if staminaMinutes == 0 then - return - end - - local playerId = player:getId() - if not nextUseStaminaTime[playerId] then - nextUseStaminaTime[playerId] = 0 - end - - local currentTime = os.time() - local timePassed = currentTime - nextUseStaminaTime[playerId] - if timePassed <= 0 then - return - end - - if timePassed > 60 then - if staminaMinutes > 2 then - staminaMinutes = staminaMinutes - 2 - else - staminaMinutes = 0 - end - nextUseStaminaTime[playerId] = currentTime + 120 - else - staminaMinutes = staminaMinutes - 1 - nextUseStaminaTime[playerId] = currentTime + 60 - end - player:setStamina(staminaMinutes) -end - function Player:onGainExperience(source, exp, rawExp, sendText) local onGainExperience = EventCallback.onGainExperience return onGainExperience and onGainExperience(self, source, exp, rawExp, sendText) or exp diff --git a/data/scripts/eventcallbacks/player/default_onGainExperience.lua b/data/scripts/eventcallbacks/player/default_onGainExperience.lua new file mode 100644 index 00000000..f327f63a --- /dev/null +++ b/data/scripts/eventcallbacks/player/default_onGainExperience.lua @@ -0,0 +1,95 @@ +local soulCondition = Condition(CONDITION_SOUL, CONDITIONID_DEFAULT) +soulCondition:setTicks(4 * 60 * 1000) +soulCondition:setParameter(CONDITION_PARAM_SOULGAIN, 1) + +local function useStamina(player) + local staminaMinutes = player:getStamina() + if staminaMinutes == 0 then + return + end + + local playerId = player:getId() + if not nextUseStaminaTime[playerId] then + nextUseStaminaTime[playerId] = 0 + end + + local currentTime = os.time() + local timePassed = currentTime - nextUseStaminaTime[playerId] + if timePassed <= 0 then + return + end + + if timePassed > 60 then + if staminaMinutes > 2 then + staminaMinutes = staminaMinutes - 2 + else + staminaMinutes = 0 + end + nextUseStaminaTime[playerId] = currentTime + 120 + else + staminaMinutes = staminaMinutes - 1 + nextUseStaminaTime[playerId] = currentTime + 60 + end + player:setStamina(staminaMinutes) +end + +local default = EventCallback + +function default.onGainExperience(player, source, exp, rawExp, sendText) + if not source or source:isPlayer() then + return exp + end + + local level = player:getLevel() + + -- Soul regeneration + local vocation = player:getVocation() + if player:getSoul() < vocation:getMaxSoul() and exp >= level then + soulCondition:setParameter(CONDITION_PARAM_SOULTICKS, vocation:getSoulGainTicks() * 1000) + player:addCondition(soulCondition) + end + + -- Apply experience stage multiplier + exp = exp * Game.getExperienceStage(level) + + -- Apply low level bonus + exp = exp * (1 + player:calculateLowLevelBonus(level) / 100) + + -- Stamina modifier + if configManager.getBoolean(configKeys.STAMINA_SYSTEM) then + useStamina(player) + + local staminaMinutes = player:getStamina() + if staminaMinutes > 2340 and player:isPremium() then + exp = exp * 1.5 + elseif staminaMinutes <= 840 then + exp = exp * 0.5 + end + end + return exp +end + +default:register() + +-- For this event, we use the trigger index math.huge so that this event is called last, thus ensuring that the +-- experience message is sent to the client with the correct value. + +local message = EventCallback + +function message.onGainExperience(player, source, exp, rawExp, sendText) + if sendText and exp ~= 0 then + local pos = player:getPosition() + local expString = exp .. (exp ~= 1 and " experience points." or " experience point.") + player:sendTextMessage(MESSAGE_EXPERIENCE, "You gained " .. expString, pos, exp, TEXTCOLOR_WHITE_EXP) + + local spectators = Game.getSpectators(pos, false, true) + for _, spectator in ipairs(spectators) do + if spectator ~= player then + spectator:sendTextMessage(MESSAGE_EXPERIENCE_OTHERS, player:getName() .. " gained " .. expString) + end + end + end + return exp +end + +message:register(math.huge) diff --git a/data/scripts/eventcallbacks/player/default_onLookInMarket.lua b/data/scripts/eventcallbacks/player/default_onLookInMarket.lua new file mode 100644 index 00000000..5d4eadb7 --- /dev/null +++ b/data/scripts/eventcallbacks/player/default_onLookInMarket.lua @@ -0,0 +1,311 @@ +local showAtkWeaponTypes = {WEAPON_CLUB, WEAPON_SWORD, WEAPON_AXE, WEAPON_DISTANCE} +local showDefWeaponTypes = {WEAPON_CLUB, WEAPON_SWORD, WEAPON_AXE, WEAPON_DISTANCE, WEAPON_SHIELD} + +local event = EventCallback + +event.onLookInMarket = function(self, itemType) + local response = NetworkMessage() + response:addByte(0xF8) + response:addU16(itemType:getClientId()) + + -- tier label (byte) + do + if itemType:getClassification() > 0 then + response:addByte(0) + end + end + + -- armor + do + local armor = itemType:getArmor() + if armor > 0 then + response:addString(armor) + else + response:addU16(0) + end + end + + -- weapon data (will be reused) + local weaponType = itemType:getWeaponType() + + -- attack + do + local showAtk = table.contains(showAtkWeaponTypes, weaponType) + if showAtk then + local atkAttrs = {} + local atk = itemType:getAttack() + if itemType:isBow() then + if atk ~= 0 then + atkAttrs[#atkAttrs + 1] = string.format("%+d", atk) + end + + local hitChance = itemType:getHitChance() + if hitChance ~= 0 then + atkAttrs[#atkAttrs + 1] = string.format("chance to hit %+d%%", hitChance) + end + + atkAttrs[#atkAttrs + 1] = string.format("%d fields", itemType:getShootRange()) + else + atkAttrs[#atkAttrs + 1] = atk + local elementDmg = itemType:getElementDamage() + if elementDmg ~= 0 then + atkAttrs[#atkAttrs] = string.format("%d physical %+d %s", atkAttrs[#atkAttrs], elementDmg, getCombatName(itemType:getElementType())) + end + end + + response:addString(table.concat(atkAttrs, ", ")) + else + response:addU16(0) + end + end + + -- container slots + do + if itemType:isContainer() then + response:addString(itemType:getCapacity()) + else + response:addU16(0) + end + end + + -- defense + do + local showDef = table.contains(showDefWeaponTypes, weaponType) + if showDef then + local def = itemType:getDefense() + if weaponType == WEAPON_DISTANCE then + -- throwables + local ammoType = itemType:getAmmoType() + if ammoType ~= AMMO_ARROW and ammoType ~= AMMO_BOLT then + response:addString(def) + else + response:addU16(0) + end + else + -- extra def + local xD = itemType:getExtraDefense() + if xD ~= 0 then + def = string.format("%d %+d", def, xD) + end + + response:addString(def) + end + else + response:addU16(0) + end + end + + -- description + do + local desc = itemType:getDescription() + if desc and #desc > 0 then + response:addString(desc:sub(1, -2)) + else + response:addU16(0) + end + end + + -- duration + do + local duration = itemType:getDuration() + if duration == 0 then + local transferType = itemType:getTransformEquipId() + if transferType ~= 0 then + transferType = ItemType(transferType) + duration = transferType and transferType:getDuration() or duration + end + end + + if duration > 0 then + response:addString(Game.getCountdownString(duration, true, true)) + else + response:addU16(0) + end + end + + -- item abilities (will be reused) + local abilities = itemType:getAbilities() + + -- element protections + do + local protections = {} + for element, value in pairs(abilities.absorbPercent) do + if value ~= 0 then + protections[#protections + 1] = string.format("%s %+d%%", getCombatName(2 ^ (element - 1)), value) + end + end + + if #protections > 0 then + response:addString(table.concat(protections, ", ")) + else + response:addU16(0) + end + end + + -- level req + do + local minLevel = itemType:getMinReqLevel() + if minLevel > 0 then + response:addString(minLevel) + else + response:addU16(0) + end + end + + -- magic level req + do + local minMagicLevel = itemType:getMinReqMagicLevel() + if minMagicLevel > 0 then + response:addString(minMagicLevel) + else + response:addU16(0) + end + end + + -- vocation + do + local vocations = itemType:getVocationString() + if vocations and vocations:len() > 0 then + response:addString(vocations) + else + response:addU16(0) + end + end + + -- rune words + do + local spellName = itemType:getRuneSpellName() + if spellName and spellName:len() > 0 then + response:addString(spellName) + else + response:addU16(0) + end + end + + -- "skill boost" category + do + -- atk speed + local atkSpeed = itemType:getAttackSpeed() + local skillBoosts = {} + if atkSpeed ~= 0 then + skillBoosts[#skillBoosts + 1] = string.format("attack speed %0.2f/turn", 2000 / atkSpeed) + end + + -- skill boost + if abilities.manaGain > 0 or abilities.healthGain > 0 or abilities.regeneration then + skillBoosts[#skillBoosts + 1] = "faster regeneration" + end + + -- invisibility + if abilities.invisible then + skillBoosts[#skillBoosts + 1] = "invisibility" + end + + -- magic shield (classic) + if abilities.manaShield then + skillBoosts[#skillBoosts + 1] = "magic shield" + end + + -- stats (hp/mp/soul/ml) + for stat, value in pairs(abilities.stats) do + if value ~= 0 then + skillBoosts[#skillBoosts + 1] = string.format("%s %+d", getStatName(stat - 1), value) + end + end + + -- stats but in % + for stat, value in pairs(abilities.statsPercent) do + if value ~= 0 then + skillBoosts[#skillBoosts + 1] = string.format("%s %+d%%", getStatName(stat - 1), value) + end + end + + -- speed + if abilities.speed ~= 0 then + skillBoosts[#skillBoosts + 1] = string.format("speed %+d", math.floor(abilities.speed / 2)) + end + + -- skills + for skill, value in pairs(abilities.skills) do + if value ~= 0 then + skillBoosts[#skillBoosts + 1] = string.format("%s %+d", getSkillName(skill - 1), value) + end + end + + -- special skills + for skill, value in pairs(abilities.specialSkills) do + if value ~= 0 then + skillBoosts[#skillBoosts + 1] = string.format("%s %+d", getSpecialSkillName[skill - 1], value) + end + end + + -- add to response + if #skillBoosts > 0 then + response:addString(table.concat(skillBoosts, ", ")) + else + response:addU16(0) + end + end + + -- charges + do + if itemType:hasShowCharges() then + response:addString(itemType:getCharges()) + else + response:addU16(0) + end + end + + -- weapon type + do + if itemType:isWeapon() then + response:addString(itemType:getWeaponString()) + else + response:addU16(0) + end + end + + -- weight + response:addString(string.format("%0.2f", itemType:getWeight() / 100)) + + -- to do + response:addU16(0) -- Imbuement Slots + response:addU16(0) -- Magic Shield Capacity + response:addU16(0) -- Cleave + response:addU16(0) -- Damage Reflection + response:addU16(0) -- Perfect Shot + response:addU16(0) -- Classification + response:addU16(0) -- Tier + + -- buy stats + do + local stats = itemType:getMarketBuyStatistics() + if stats then + response:addByte(0x01) + response:addU32(stats.numTransactions) + response:addU64(stats.totalPrice) + response:addU64(stats.highestPrice) + response:addU64(stats.lowestPrice) + else + response:addByte(0x00) + end + end + + -- sell stats + do + local stats = itemType:getMarketSellStatistics() + if stats then + response:addByte(0x01) + response:addU32(stats.numTransactions) + response:addU64(stats.totalPrice) + response:addU64(stats.highestPrice) + response:addU64(stats.lowestPrice) + else + response:addByte(0x00) + end + end + + response:sendToPlayer(self) +end + +event:register() diff --git a/data/scripts/eventcallbacks/player/default_onLookInShop.lua b/data/scripts/eventcallbacks/player/default_onLookInShop.lua new file mode 100644 index 00000000..49150b4c --- /dev/null +++ b/data/scripts/eventcallbacks/player/default_onLookInShop.lua @@ -0,0 +1,25 @@ +local event = EventCallback + +event.onLookInShop = function(self, itemType, count, description) + local description = "You see " .. itemType:getItemDescription() + if self:getGroup():getAccess() then + description = string.format("%s\nItem ID: %d", description, itemType:getId()) + description = string.format("%s\nClient ID: %d", description, itemType:getClientId()) + + local transformEquipId = itemType:getTransformEquipId() + local transformDeEquipId = itemType:getTransformDeEquipId() + if transformEquipId ~= 0 then + description = string.format("%s\nTransforms to: %d (onEquip)", description, transformEquipId) + elseif transformDeEquipId ~= 0 then + description = string.format("%s\nTransforms to: %d (onDeEquip)", description, transformDeEquipId) + end + + local decayId = itemType:getDecayId() + if decayId ~= -1 then + description = string.format("%s\nDecays to: %d", description, decayId) + end + end + return description +end + +event:register() diff --git a/data/scripts/eventcallbacks/player/default_onRotateItem.lua b/data/scripts/eventcallbacks/player/default_onRotateItem.lua new file mode 100644 index 00000000..fe7696bc --- /dev/null +++ b/data/scripts/eventcallbacks/player/default_onRotateItem.lua @@ -0,0 +1,10 @@ +local ec = EventCallback + +ec.onRotateItem = function(self, item) + local newId = item:getType():getRotateTo() + if newId ~= 0 then + item:transform(newId) + end +end + +ec:register() diff --git a/data/scripts/eventcallbacks/player/default_onSpellTry.lua b/data/scripts/eventcallbacks/player/default_onSpellTry.lua new file mode 100644 index 00000000..4ac69a05 --- /dev/null +++ b/data/scripts/eventcallbacks/player/default_onSpellTry.lua @@ -0,0 +1,7 @@ +local ec = EventCallback + +ec.onSpellTry = function(self, spell, spellType) + return true +end + +ec:register()