finish market system

This commit is contained in:
ErikasKontenis
2022-04-10 22:15:53 +03:00
parent fadbf8b64d
commit 6e6b2dc4a6
25 changed files with 2670 additions and 1166 deletions

View File

@@ -25,4 +25,5 @@
<event class="Player" method="onGainExperience" enabled="1" />
<event class="Player" method="onLoseExperience" enabled="0" />
<event class="Player" method="onGainSkillTries" enabled="1" />
<event class="Player" method="onLookInMarket" enabled="1" />
</events>

View File

@@ -218,6 +218,293 @@ function Player:onLookInTrade(partner, item, distance)
self:sendTextMessage(MESSAGE_INFO_DESCR, "You see " .. item:getDescription(distance))
end
local showAtkWeaponTypes = {WEAPON_CLUB, WEAPON_SWORD, WEAPON_AXE, WEAPON_DISTANCE}
local showDefWeaponTypes = {WEAPON_CLUB, WEAPON_SWORD, WEAPON_AXE, WEAPON_DISTANCE, WEAPON_SHIELD}
function Player:onLookInMarket(itemType)
local response = NetworkMessage()
response:addByte(0xF8)
response:addU16(itemType:getId())
-- 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 = 0
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
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
-- skill boost
local skillBoosts = {}
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
-- 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
function Player:onMoveItem(item, count, fromPosition, toPosition, fromCylinder, toCylinder)
return true
end

View File

@@ -138,7 +138,8 @@ function onStartup()
db.asyncQuery("DELETE FROM `guild_wars` WHERE `status` = 0")
db.asyncQuery("DELETE FROM `players` WHERE `deletion` != 0 AND `deletion` < " .. os.time())
db.asyncQuery("DELETE FROM `ip_bans` WHERE `expires_at` != 0 AND `expires_at` <= " .. os.time())
db.asyncQuery("DELETE FROM `market_history` WHERE `inserted` <= " .. (os.time() - configManager.getNumber(configKeys.MARKET_OFFER_DURATION)))
-- Move expired bans to ban history
local resultId = db.storeQuery("SELECT * FROM `account_bans` WHERE `expires_at` != 0 AND `expires_at` <= " .. os.time())
if resultId ~= false then

View File

@@ -14,3 +14,105 @@ local slotBits = {
function ItemType.usesSlot(self, slot)
return bit.band(self:getSlotPosition(), slotBits[slot] or 0) ~= 0
end
function ItemType.isHelmet(self)
return self:usesSlot(CONST_SLOT_HEAD)
end
function ItemType.isArmor(self)
return self:usesSlot(CONST_SLOT_ARMOR)
end
function ItemType.isLegs(self)
return self:usesSlot(CONST_SLOT_LEGS)
end
function ItemType.isBoots(self)
return self:usesSlot(CONST_SLOT_FEET)
end
local notWeapons = {WEAPON_NONE, WEAPON_SHIELD, WEAPON_AMMO}
function ItemType.isWeapon(self)
return not table.contains(notWeapons, self:getWeaponType())
end
function ItemType.isTwoHanded(self)
return bit.band(self:getSlotPosition(), SLOTP_TWO_HAND) ~= 0
end
function ItemType.isBow(self)
local ammoType = self:getAmmoType()
return self:getWeaponType() == WEAPON_DISTANCE and (ammoType == AMMO_ARROW or ammoType == AMMO_BOLT)
end
function ItemType.isMissile(self)
local ammoType = self:getAmmoType()
return self:getWeaponType() == WEAPON_DISTANCE and ammoType ~= AMMO_ARROW and ammoType ~= AMMO_BOLT
end
function ItemType.isWand(self)
return self:getWeaponType() == WEAPON_WAND
end
function ItemType.isShield(self)
return self:getWeaponType() == WEAPON_SHIELD
end
function ItemType.isBackpack(self)
return self:usesSlot(CONST_SLOT_BACKPACK)
end
function ItemType.isNecklace(self)
return self:usesSlot(CONST_SLOT_NECKLACE)
end
function ItemType.isRing(self)
return self:usesSlot(CONST_SLOT_RING)
end
function ItemType.isAmmo(self)
return self:getWeaponType() == WEAPON_AMMO
end
function ItemType.isTrinket(self)
return self:usesSlot(CONST_SLOT_AMMO) and self:getWeaponType() == WEAPON_NONE
end
function ItemType.isKey(self)
return self:getType() == ITEM_TYPE_KEY
end
function ItemType.isBed(self)
return self:getType() == ITEM_TYPE_BED
end
function ItemType.isSplash(self)
return self:getGroup() == ITEM_GROUP_SPLASH
end
function ItemType.isPodium(self)
return self:getGroup() == ITEM_GROUP_PODIUM
end
function ItemType.getWeaponString(self)
local weaponType = self:getWeaponType()
local weaponString = "unknown"
if weaponType == WEAPON_CLUB then
weaponString = "blunt instrument"
elseif weaponType == WEAPON_SWORD then
weaponString = "stabbing weapon"
elseif weaponType == WEAPON_AXE then
weaponString = "cutting weapon"
elseif weaponType == WEAPON_DISTANCE then
weaponString = self:isBow() and "firearm" or "missile"
elseif weaponType == WEAPON_WAND then
weaponString = "wand/rod"
end
if self:isTwoHanded() then
weaponString = string.format("%s, two-handed", weaponString)
end
return weaponString
end