forgottenserver/data/scripts/network/cyclopedia_character.lua
2023-12-13 23:22:09 +01:00

241 lines
5.9 KiB
Lua

local function sendBasicInfo(self, msg)
msg:addString(self:getName())
msg:addString(self:getVocation():getName())
msg:addU16(self:getLevel())
local outfit = self:getOutfit()
if outfit.lookType ~= 0 then
msg:addU16(outfit.lookType)
msg:addByte(outfit.lookHead)
msg:addByte(outfit.lookBody)
msg:addByte(outfit.lookLegs)
msg:addByte(outfit.lookFeet)
msg:addByte(outfit.lookAddons)
else
msg:addU16(outfit.lookTypeEx)
end
msg:addByte(0) -- hide stamina
msg:addByte(1) -- enable store summary & character titles
msg:addString("") -- character title
msg:sendToPlayer(self)
msg:delete()
return true
end
local function sendCombatStats(self, msg)
for skillId = SPECIALSKILL_CRITICALHITCHANCE, SPECIALSKILL_MANALEECHAMOUNT do
msg:addU16(self:getSpecialSkill(skillId))
msg:addU16(0) -- base special skill
end
-- fatal, dodge, momentum
for i = 1, 3 do
msg:addU16(0)
msg:addU16(0)
end
msg:addU16(0) -- cleave (bonus percent damage to nearby enemies)
msg:addU16(0) -- bonus magic shield capacity (flat)
msg:addU16(0) -- bonus magic shield capacity (percent)
-- perfect shot flat damage bonus at 1-5 range
for i = 1, 5 do
msg:addU16(0)
end
msg:addU16(0) -- damage reflection (flat, one value for all combat types)
msg:addByte(self:getBlessings())
msg:addByte(8) -- blessings count
-- weapon
msg:addU16(0) -- base max damage
msg:addByte(0) -- base element type
msg:addByte(0) -- percent damage conversion
msg:addByte(0) -- conversion element type
msg:addU16(self:getTotalArmor())
msg:addU16(self:getTotalDefense())
msg:addDouble(0) -- damage mitigation (in %)
-- element resistances count
msg:addByte(0)
-- structure:
-- u8 clientcombat
-- u8 value
-- active potions count
msg:addByte(0)
-- structure:
-- item clientId
-- u16 duration
msg:sendToPlayer(self)
msg:delete()
return true
end
local clientSkillsId = {
[0] = CYCLOPEDIA_SKILL_FIST,
[1] = CYCLOPEDIA_SKILL_CLUB,
[2] = CYCLOPEDIA_SKILL_SWORD,
[3] = CYCLOPEDIA_SKILL_AXE,
[4] = CYCLOPEDIA_SKILL_DISTANCE,
[5] = CYCLOPEDIA_SKILL_SHIELDING,
[6] = CYCLOPEDIA_SKILL_FISHING
}
local function sendGeneralStats(self, msg)
msg:addU64(self:getExperience())
msg:addU16(self:getLevel())
msg:addByte(self:getLevelPercent())
msg:addU16(self:getClientExpDisplay())
msg:addU32(0) -- tournament exp (deprecated)
msg:addU16(self:getClientLowLevelBonusDisplay())
msg:addU16(0) -- store exp bonus
msg:addU16(self:getClientStaminaBonusDisplay())
msg:addU16(0) -- exp boost remaining time
msg:addByte(0) -- enable exp boost store button
msg:addU32(self:getHealth())
msg:addU32(self:getMaxHealth())
msg:addU32(self:getMana())
msg:addU32(self:getMaxMana())
msg:addByte(self:getSoul())
msg:addU16(self:getStamina())
local foodTime = 0
local condition = self:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT)
if condition then
foodTime = condition:getTicks() / 1000
end
msg:addU16(foodTime)
msg:addU16(self:getOfflineTrainingTime() / 60 / 1000)
msg:addU16(self:getSpeed() / 2)
msg:addU16(self:getBaseSpeed() / 2)
local infiniteCapacity = self:hasFlag(PlayerFlag_HasInfiniteCapacity) and 1000000
msg:addU32(infiniteCapacity or self:getCapacity()) -- base + bonus capacity
msg:addU32(infiniteCapacity or self:getCapacity())
msg:addU32(infiniteCapacity or self:getFreeCapacity())
msg:addByte(CYCLOPEDIA_SKILL_AMOUNT)
msg:addByte(CYCLOPEDIA_SKILL_MAGIC)
msg:addU16(self:getMagicLevel())
msg:addU16(self:getBaseMagicLevel())
msg:addU16(self:getBaseMagicLevel()) -- base + loyalty bonus
msg:addU16(self:getMagicLevelPercent() * 100)
for i = SKILL_FIST, SKILL_FISHING, 1 do
msg:addByte(clientSkillsId[i])
msg:addU16(self:getEffectiveSkillLevel(i))
msg:addU16(self:getSkillLevel(i))
-- base + loyalty bonus
msg:addU16(self:getSkillLevel(i))
msg:addU16(self:getSkillPercent(i) * 100)
end
msg:addByte(0) -- magic boost (element and value)
msg:sendToPlayer(self)
msg:delete()
return true
end
local function sendAchievements(self, msg)
local achievementIds = self:getAchievements()
msg:addU16(self:getAchievementPoints())
msg:addU16(#getSecretAchievements())
msg:addU16(#achievementIds)
for _, id in pairs(achievementIds) do
local achievement = achievements[id]
local secret = achievement.secret
msg:addU16(achievement.clientId)
msg:addU32(self:getStorageValue(PlayerStorageKeys.achievementsBase + id))
msg:addByte(secret and 0x01 or 0x00)
if secret then
msg:addString(achievement.name)
msg:addString(achievement.description)
msg:addByte(achievement.grade)
end
end
msg:sendToPlayer(self)
msg:delete()
return true
end
local function sendBadges(self, msg)
msg:addByte(0x01) -- show account info
msg:addByte(0x01) -- account online
msg:addByte(self:isPremium() and 1 or 0)
msg:addString("") -- loyalty title
msg:addByte(0) -- badges count
-- structure:
-- u32 badge id
-- string badge name
msg:sendToPlayer(self)
msg:delete()
return true
end
local BASIC_INFO = 0x00
local GENERAL_STATS = 0x01
local COMBAT_STATS = 0x02
local ACHIEVEMENTS = 0x05
local BADGES = 0x0A
--[[
local RECENT_DEATHS = 0x03
local RECENT_PVP_KILLS = 0x04
local ITEM_SUMMARY = 0x06
local APPEARANCES = 0x07
local STORE = 0x08
local INSPECTION = 0x09
local TITLES = 0x0B
]]--
local handlers = {
[BASIC_INFO] = sendBasicInfo,
[GENERAL_STATS] = sendGeneralStats,
[COMBAT_STATS] = sendCombatStats,
[ACHIEVEMENTS] = sendAchievements,
[BADGES] = sendBadges,
--[[
[RECENT_DEATHS] = sendRecentDeaths,
[RECENT_PVP_KILLS] = sendRecentPvpKills,
[ITEM_SUMMARY] = sendItemSummary,
[APPEARANCES] = sendAppearances,
[STORE] = sendStore,
[INSPECTION] = sendInspection,
[TITLES] = sendTitles
]]--
}
local handler = PacketHandler(0xE5)
function handler.onReceive(player, msg)
msg:skipBytes(4)
local type = msg:getByte()
local method = handlers[type]
if method then
local msg = NetworkMessage()
msg:addByte(0xDA)
msg:addByte(type)
msg:addByte(0x00)
method(player, msg)
end
end
handler:register()