A few Lua scripts updates, converted Lua scripts to RevScriptSys (#431)

- changed folder name from LUA to Lua
- Added installation instructions
- fixed playerdeath variables (fixes #430)
- Added outfit IDs up to Jouster outfit to the sync outfit script
- Removed unecessary instruction
- Added revscriptsys version of all scripts
This commit is contained in:
Evil Puncker 2020-07-03 14:31:44 -03:00 committed by GitHub
parent 3c8b1eb0aa
commit 34f9b51f8f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 1010 additions and 275 deletions

View File

@ -1,70 +0,0 @@
-- With Rookgaard
--[[
local firstItems = {2050, 2382} -- torch and club
function onLogin(player)
if player:getLastLoginSaved() <= 0 then
for i = 1, #firstItems do
player:addItem(firstItems[i], 1)
end
player:addItem(player:getSex() == 0 and 2651 or 2650, 1) -- coat
player:addItem(ITEM_BAG, 1)
player:addItem(2674, 1) -- red apple
end
return true
end
]]--
-- Without Rookgaard
local config = {
[1] = { -- Sorcerer
-- equipment: spellbook, wand of vortex, magician's robe, mage hat, studded legs, leather boots, scarf
items = {{2175, 1}, {2190, 1}, {8819, 1}, {8820, 1}, {2468, 1}, {2643, 1}, {2661, 1}},
-- container: rope, shovel, mana potion
container = {{2120, 1}, {2554, 1}, {7620, 1}}
},
[2] = { -- Druid
-- equipment: spellbook, snakebite rod, magician's robe, mage hat, studded legs, leather boots, scarf
items = {{2175, 1}, {2182, 1}, {8819, 1}, {8820, 1}, {2468, 1}, {2643, 1}, {2661, 1}},
-- container: rope, shovel, mana potion
container = {{2120, 1}, {2554, 1}, {7620, 1}}
},
[3] = { -- Paladin
-- equipment: dwarven shield, 5 spear, ranger's cloak, ranger legs, scarf, legion helmet
items = {{2525, 1}, {2389, 5}, {2660, 1}, {8923, 1}, {2643, 1}, {2661, 1}, {2480, 1}},
-- container: rope, shovel, health potion, bow, 50 arrow
container = {{2120, 1}, {2554, 1}, {7618, 1}, {2456, 1}, {2544, 50}}
},
[4] = { -- Knight
-- equipment: dwarven shield, steel axe, brass armor, brass helmet, brass legs, scarf
items = {{2525, 1}, {8601, 1}, {2465, 1}, {2460, 1}, {2478, 1}, {2643, 1}, {2661, 1}},
-- container jagged sword, daramanian mace, rope, shovel, health potion
container = {{8602, 1}, {2439, 1}, {2120, 1}, {2554, 1}, {7618, 1}}
}
}
function onLogin(player)
local targetVocation = config[player:getVocation():getId()]
if not targetVocation then
return true
end
if player:getLastLoginSaved() ~= 0 then
return true
end
for i = 1, #targetVocation.items do
player:addItem(targetVocation.items[i][1], targetVocation.items[i][2])
end
local backpack = player:addItem(1988)
if not backpack then
return true
end
for i = 1, #targetVocation.container do
backpack:addItem(targetVocation.container[i][1], targetVocation.container[i][2])
end
return true
end

View File

@ -1,7 +0,0 @@
1. Add below line to XML file: data/creaturescripts/creaturescripts.xml
<event type="login" name="znote_syncoutfits" script="syncoutfit.lua" />
2. Register event in login.lua: data/creaturescripts/scripts/login.lua
player:registerEvent("znote_syncoutfits")
3. Place Lua file syncoutfit.lua in folder: data/creaturescripts/scripts/

View File

@ -1,39 +0,0 @@
-- Sync outfits that player own with Znote AAC
-- So its possible to see which full sets player
-- has in characterprofile.php
znote_outfit_list = {
{ -- Female (girl) outfits
136,137,138,139,140,141,142,147,148,
149,150,155,156,157,158,252,269,270,
279,288,324,329,336,366,431,433,464,
466,471,513,514,542,575,578,618,620,
632,635,636,664,666,683,694,696,698,
724,732,745,749,759,845,852,874,885,
900
},
{ -- Male (boy) outfits
128,129,130,131,132,133,134,143,144,
145,146,151,152,153,154,251,268,273,
278,289,325,328,335,367,430,432,463,
465,472,512,516,541,574,577,610,619,
633,634,637,665,667,684,695,697,699,
725,733,746,750,760,846,853,873,884,
899
}
}
function onLogin(player)
-- storage_value + 1000 storages (highest outfit id) must not be used in other script.
-- Must be identical to Znote AAC config.php: $config['EQ_shower'] -> storage_value
local storage_value = 10000
-- Loop through outfits
for _, outfit in pairs(znote_outfit_list[player:getSex()+1]) do
if player:hasOutfit(outfit,3) then
if player:getStorageValue(storage_value + outfit) ~= 3 then
player:setStorageValue(storage_value + outfit, 3)
end
end
end
return true
end

View File

@ -0,0 +1,114 @@
-- With Rookgaard
--[[
local firstItems = {2050, 2382} -- torch and club
function onLogin(player)
if player:getLastLoginSaved() <= 0 then
for i = 1, #firstItems do
player:addItem(firstItems[i], 1)
end
player:addItem(player:getSex() == 0 and 2651 or 2650, 1) -- coat
player:addItem(ITEM_BAG, 1)
player:addItem(2674, 1) -- red apple
end
return true
end
]]--
-- Without Rookgaard
local config = {
[1] = { -- Sorcerer
items = {
{2175, 1}, -- spellbook
{2190, 1}, -- wand of vortex
{8819, 1}, -- magician's robe
{8820, 1}, -- mage hat
{2468, 1}, -- studded legs
{2643, 1}, -- leather boots
{2661, 1} -- scarf
},
container = {
{2120, 1}, -- rope
{2554, 1}, -- shovel
{7620, 1} -- mana potion
}
},
[2] = { -- Druid
items = {
{2175, 1}, -- spellbook
{2182, 1}, -- snakebite rod
{8819, 1}, -- magician's robe
{8820, 1}, -- mage hat
{2468, 1}, -- studded legs
{2643, 1}, -- leather boots
{2661, 1} -- scarf
},
container = {
{2120, 1}, -- rope
{2554, 1}, -- shovel
{7620, 1} -- mana potion
}
},
[3] = { -- Paladin
items = {
{2525, 1}, -- dwarven shield
{2389, 5}, -- 5 spears
{2660, 1}, -- ranger's cloak
{8923, 1}, -- ranger legs
{2643, 1}, -- leather boots
{2661, 1}, -- scarf
{2480, 1} -- legion helmet
},
container = {
{2120, 1}, -- rope
{2554, 1}, -- shovel
{7618, 1}, -- health potion
{2456, 1}, -- bow
{2544, 50} -- 50 arrows
}
},
[4] = { -- Knight
items = {
{2525, 1}, -- dwarven shield
{8601, 1}, -- steel axe
{2465, 1}, -- brass armor
{2460, 1}, -- brass helmet
{2478, 1}, -- brass legs
{2643, 1}, -- leather boots
{2661, 1} -- scarf
},
container = {
{8602, 1}, -- jagged sword
{2439, 1}, -- daramanian mace
{2120, 1}, -- rope
{2554, 1}, -- shovel
{7618, 1} -- health potion
}
}
}
function onLogin(player)
local targetVocation = config[player:getVocation():getId()]
if not targetVocation then
return true
end
if player:getLastLoginSaved() ~= 0 then
return true
end
for i = 1, #targetVocation.items do
player:addItem(targetVocation.items[i][1], targetVocation.items[i][2])
end
local backpack = player:addItem(1988)
if not backpack then
return true
end
for i = 1, #targetVocation.container do
backpack:addItem(targetVocation.container[i][1], targetVocation.container[i][2])
end
return true
end

View File

@ -0,0 +1,3 @@
Step 1: Replace the one that comes with tfs with this one
Step 2: Restart OT server, and it should work. :)

View File

@ -78,7 +78,7 @@ function onDeath(player, corpse, killer, mostDamageKiller, lastHitUnjustified, m
end
local playerGuid = player:getGuid()
db.query("INSERT INTO `player_deaths` (`player_id`, `time`, `level`, `killed_by`, `is_player`, `mostdamage_by`, `mostdamage_is_player`, `unjustified`, `mostdamage_unjustified`) VALUES (" .. playerGuid .. ", " .. os.time() .. ", " .. player:getLevel() .. ", " .. db.escapeString(killerName) .. ", " .. byPlayer .. ", " .. db.escapeString(mostDamageName) .. ", " .. byPlayerMostDamage .. ", " .. (unjustified and 1 or 0) .. ", " .. (mostDamage_unjustified and 1 or 0) .. ")")
db.query("INSERT INTO `player_deaths` (`player_id`, `time`, `level`, `killed_by`, `is_player`, `mostdamage_by`, `mostdamage_is_player`, `unjustified`, `mostdamage_unjustified`) VALUES (" .. playerGuid .. ", " .. os.time() .. ", " .. player:getLevel() .. ", " .. db.escapeString(killerName) .. ", " .. byPlayer .. ", " .. db.escapeString(mostDamageName) .. ", " .. byPlayerMostDamage .. ", " .. (lastHitUnjustified and 1 or 0) .. ", " .. (mostDamageUnjustified and 1 or 0) .. ")")
local resultId = db.storeQuery("SELECT `player_id` FROM `player_deaths` WHERE `player_id` = " .. playerGuid)
local deathRecords = 0

View File

@ -0,0 +1,4 @@
1. Add below line to XML file: data/creaturescripts/creaturescripts.xml
<event type="login" name="znote_syncoutfits" script="syncoutfit.lua" />
2. Place Lua file syncoutfit.lua in folder: data/creaturescripts/scripts/

View File

@ -0,0 +1,46 @@
-- Sync outfits that player own with Znote AAC
-- So its possible to see which full sets player
-- has in characterprofile.php
znote_outfit_list = {
{ -- Female outfits
136, 137, 138, 139, 140, 141, 142, 147, 148,
149, 150, 155, 156, 157, 158, 252, 269, 270,
279, 288, 324, 329, 336, 366, 431, 433, 464,
466, 471, 513, 514, 542, 575, 578, 618, 620,
632, 635, 636, 664, 666, 683, 694, 696, 698,
724, 732, 745, 749, 759, 845, 852, 874, 885,
900, 973, 975, 1020, 1024, 1043, 1050, 1057,
1070, 1095, 1103, 1128, 1147, 1162, 1174,
1187, 1203, 1205, 1207, 1211, 1246, 1244,
1252, 1271, 1280, 1283, 1289, 1293, 1332
},
{ -- Male outfits
128, 129, 130, 131, 132, 133, 134, 143, 144,
145, 146, 151, 152, 153, 154, 251, 268, 273,
278, 289, 325, 328, 335, 367, 430, 432, 463,
465, 472, 512, 516, 541, 574, 577, 610, 619,
633, 634, 637, 665, 667, 684, 695, 697, 699,
725, 733, 746, 750, 760, 846, 853, 873, 884,
899, 908, 931, 955, 957, 962, 964, 966, 968,
970, 972, 974, 1021, 1023, 1042, 1051, 1056,
1069, 1094, 1102, 1127, 1146, 1161, 1173,
1186, 1202, 1204, 1206, 1210, 1245, 1243,
1251, 1270, 1279, 1282, 1288, 1292, 1331
}
}
function onLogin(player)
-- storage_value + 1000 storages (highest outfit id) must not be used in other script.
-- Must be identical to Znote AAC config.php: $config['EQ_shower'] -> storage_value
local storage_value = 10000
-- Loop through outfits
for _, outfit in pairs(znote_outfit_list[player:getSex() + 1]) do
if player:hasOutfit(outfit,3) then
if player:getStorageValue(storage_value + outfit) ~= 3 then
player:setStorageValue(storage_value + outfit, 3)
end
end
end
return true
end

View File

@ -0,0 +1,3 @@
Step 1: Put script on data/script folder (edit content if necessary)
Step 2: Restart OT server, and it should work. :)

View File

@ -0,0 +1,99 @@
local creatureevent = CreatureEvent("FirstItems")
local config = {
[1] = { -- Sorcerer
items = {
{2175, 1}, -- spellbook
{2190, 1}, -- wand of vortex
{8819, 1}, -- magician's robe
{8820, 1}, -- mage hat
{2468, 1}, -- studded legs
{2643, 1}, -- leather boots
{2661, 1} -- scarf
},
container = {
{2120, 1}, -- rope
{2554, 1}, -- shovel
{7620, 1} -- mana potion
}
},
[2] = { -- Druid
items = {
{2175, 1}, -- spellbook
{2182, 1}, -- snakebite rod
{8819, 1}, -- magician's robe
{8820, 1}, -- mage hat
{2468, 1}, -- studded legs
{2643, 1}, -- leather boots
{2661, 1} -- scarf
},
container = {
{2120, 1}, -- rope
{2554, 1}, -- shovel
{7620, 1} -- mana potion
}
},
[3] = { -- Paladin
items = {
{2525, 1}, -- dwarven shield
{2389, 5}, -- 5 spears
{2660, 1}, -- ranger's cloak
{8923, 1}, -- ranger legs
{2643, 1}, -- leather boots
{2661, 1}, -- scarf
{2480, 1} -- legion helmet
},
container = {
{2120, 1}, -- rope
{2554, 1}, -- shovel
{7618, 1}, -- health potion
{2456, 1}, -- bow
{2544, 50} -- 50 arrows
}
},
[4] = { -- Knight
items = {
{2525, 1}, -- dwarven shield
{8601, 1}, -- steel axe
{2465, 1}, -- brass armor
{2460, 1}, -- brass helmet
{2478, 1}, -- brass legs
{2643, 1}, -- leather boots
{2661, 1} -- scarf
},
container = {
{8602, 1}, -- jagged sword
{2439, 1}, -- daramanian mace
{2120, 1}, -- rope
{2554, 1}, -- shovel
{7618, 1} -- health potion
}
}
}
function creatureevent.onLogin(player)
local targetVocation = config[player:getVocation():getId()]
if not targetVocation then
return true
end
if player:getLastLoginSaved() ~= 0 then
return true
end
for i = 1, #targetVocation.items do
player:addItem(targetVocation.items[i][1], targetVocation.items[i][2])
end
local backpack = player:addItem(1988) -- backpack
if not backpack then
return true
end
for i = 1, #targetVocation.container do
backpack:addItem(targetVocation.container[i][1], targetVocation.container[i][2])
end
return true
end
creatureevent:register()

View File

@ -0,0 +1,17 @@
local creatureevent = CreatureEvent("FirstItemsRook")
local firstItems = {2050, 2382} -- torch and club
function creatureevent.onLogin(player)
if player:getLastLoginSaved() <= 0 then
for i = 1, #firstItems do
player:addItem(firstItems[i], 1)
end
player:addItem(player:getSex() == 0 and 2651 or 2650, 1) -- coat
player:addItem(ITEM_BAG, 1)
player:addItem(2674, 1) -- red apple
end
return true
end
creatureevent:register()

View File

@ -0,0 +1,135 @@
local deathListEnabled = true
local maxDeathRecords = 5
local function sendWarStatus(guildId, enemyGuildId, warId, playerName, killerName)
local guild, enemyGuild = Guild(guildId), Guild(enemyGuildId)
if not guild or not enemyGuild then
return
end
local resultId = db.storeQuery("SELECT `guild_wars`.`id`, (SELECT `limit` FROM `znote_guild_wars` WHERE `znote_guild_wars`.`id` = `guild_wars`.`id`) AS `limit`, (SELECT COUNT(1) FROM `guildwar_kills` WHERE `guildwar_kills`.`warid` = `guild_wars`.`id` AND `guildwar_kills`.`killerguild` = `guild_wars`.`guild1`) guild1_kills, (SELECT COUNT(1) FROM `guildwar_kills` WHERE `guildwar_kills`.`warid` = `guild_wars`.`id` AND `guildwar_kills`.`killerguild` = `guild_wars`.`guild2`) guild2_kills FROM `guild_wars` WHERE (`guild1` = " .. guildId .. " OR `guild2` = " .. guildId .. ") AND `status` = 1 AND `id` = " .. warId)
if resultId then
local guild1_kills = result.getNumber(resultId, "guild1_kills")
local guild2_kills = result.getNumber(resultId, "guild2_kills")
local limit = result.getNumber(resultId, "limit")
result.free(resultId)
local members = guild:getMembersOnline()
for i = 1, #members do
members[i]:sendChannelMessage("", string.format("%s was killed by %s. The new score is %d:%d frags (limit: %d)", playerName, killerName, guild1_kills, guild2_kills, limit), TALKTYPE_CHANNEL_R1, CHANNEL_GUILD)
end
local enemyMembers = enemyGuild:getMembersOnline()
for i = 1, #enemyMembers do
enemyMembers[i]:sendChannelMessage("", string.format("%s was killed by %s. The new score is %d:%d frags (limit: %d)", playerName, killerName, guild1_kills, guild2_kills, limit), TALKTYPE_CHANNEL_R1, CHANNEL_GUILD)
end
if guild1_kills >= limit or guild2_kills >= limit then
db.query("UPDATE `guild_wars` SET `status` = 4, `ended` = " .. os.time() .. " WHERE `status` = 1 AND `id` = " .. warId)
Game.broadcastMessage(string.format("%s has just won the war against %s.", guild:getName(), enemyGuild:getName()), MESSAGE_EVENT_ADVANCE)
end
end
end
local creatureevent = CreatureEvent("PlayerDeath")
function creatureevent.onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified, mostDamageUnjustified)
local playerId = player:getId()
if nextUseStaminaTime[playerId] then
nextUseStaminaTime[playerId] = nil
end
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are dead.")
if not deathListEnabled then
return
end
local byPlayer = 0
local killerName
if killer then
if killer:isPlayer() then
byPlayer = 1
else
local master = killer:getMaster()
if master and master ~= killer and master:isPlayer() then
killer = master
byPlayer = 1
end
end
killerName = killer:getName()
else
killerName = "field item"
end
local byPlayerMostDamage = 0
local mostDamageKillerName
if mostDamageKiller then
if mostDamageKiller:isPlayer() then
byPlayerMostDamage = 1
else
local master = mostDamageKiller:getMaster()
if master and master ~= mostDamageKiller and master:isPlayer() then
mostDamageKiller = master
byPlayerMostDamage = 1
end
end
mostDamageName = mostDamageKiller:getName()
else
mostDamageName = "field item"
end
local playerGuid = player:getGuid()
db.query("INSERT INTO `player_deaths` (`player_id`, `time`, `level`, `killed_by`, `is_player`, `mostdamage_by`, `mostdamage_is_player`, `unjustified`, `mostdamage_unjustified`) VALUES (" .. playerGuid .. ", " .. os.time() .. ", " .. player:getLevel() .. ", " .. db.escapeString(killerName) .. ", " .. byPlayer .. ", " .. db.escapeString(mostDamageName) .. ", " .. byPlayerMostDamage .. ", " .. (lastHitUnjustified and 1 or 0) .. ", " .. (mostDamageUnjustified and 1 or 0) .. ")")
local resultId = db.storeQuery("SELECT `player_id` FROM `player_deaths` WHERE `player_id` = " .. playerGuid)
local deathRecords = 0
local tmpResultId = resultId
while tmpResultId ~= false do
tmpResultId = result.next(resultId)
deathRecords = deathRecords + 1
end
if resultId ~= false then
result.free(resultId)
end
local limit = deathRecords - maxDeathRecords
if limit > 0 then
db.asyncQuery("DELETE FROM `player_deaths` WHERE `player_id` = " .. playerGuid .. " ORDER BY `time` LIMIT " .. limit)
end
if byPlayer == 1 then
local targetGuild = player:getGuild()
targetGuild = targetGuild and targetGuild:getId() or 0
if targetGuild ~= 0 then
local killerGuild = killer:getGuild()
killerGuild = killerGuild and killerGuild:getId() or 0
if killerGuild ~= 0 and targetGuild ~= killerGuild and isInWar(playerId, killer:getId()) then
local warId = false
resultId = db.storeQuery("SELECT `id` FROM `guild_wars` WHERE `status` = 1 AND ((`guild1` = " .. killerGuild .. " AND `guild2` = " .. targetGuild .. ") OR (`guild1` = " .. targetGuild .. " AND `guild2` = " .. killerGuild .. "))")
if resultId ~= false then
warId = result.getNumber(resultId, "id")
result.free(resultId)
end
if warId ~= false then
local playerName = player:getName()
db.asyncQuery("INSERT INTO `guildwar_kills` (`killer`, `target`, `killerguild`, `targetguild`, `time`, `warid`) VALUES (" .. db.escapeString(killerName) .. ", " .. db.escapeString(playerName) .. ", " .. killerGuild .. ", " .. targetGuild .. ", " .. os.time() .. ", " .. warId .. ")")
addEvent(sendWarStatus, 1000, killerGuild, targetGuild, warId, playerName, killerName)
end
end
end
end
end
creatureevent:register()
local creatureeventLogin = CreatureEvent("creatureeventLogin")
function creatureeventLogin.onLogin(player)
player:registerEvent("PlayerDeath")
return true
end
creatureeventLogin:register()

View File

@ -0,0 +1,66 @@
-- getEternalStorage and setEternalStorage
-- can be added to data/global.lua if you want to use eternal storage for another purpose than this.
-- Regular TFS global storage values get reset every time server reboots. This does not.
local function getEternalStorage(key, parser)
local value = result.getString(db.storeQuery("SELECT `value` FROM `znote_global_storage` WHERE `key` = ".. key .. ";"), "value")
if not value then
if parser then
return false
else
return -1
end
end
result.free(value)
return tonumber(value) or value
end
local function setEternalStorage(key, value)
if getEternalStorage(key, true) then
db.query("UPDATE `znote_global_storage` SET `value` = '".. value .. "' WHERE `key` = ".. key .. ";")
else
db.query("INSERT INTO `znote_global_storage` (`key`, `value`) VALUES (".. key ..", ".. value ..");")
end
return true
end
-- SQL Query to execute: --
--[[
ALTER TABLE `znote_players` ADD `exphist_lastexp` BIGINT(255) NOT NULL DEFAULT '0',
ADD `exphist1` BIGINT(255) NOT NULL DEFAULT '0',
ADD `exphist2` BIGINT(255) NOT NULL DEFAULT '0',
ADD `exphist3` BIGINT(255) NOT NULL DEFAULT '0',
ADD `exphist4` BIGINT(255) NOT NULL DEFAULT '0',
ADD `exphist5` BIGINT(255) NOT NULL DEFAULT '0',
ADD `exphist6` BIGINT(255) NOT NULL DEFAULT '0',
ADD `exphist7` BIGINT(255) NOT NULL DEFAULT '0',
ADD `onlinetimetoday` BIGINT(20) NOT NULL DEFAULT '0',
ADD `onlinetime1` BIGINT(20) NOT NULL DEFAULT '0',
ADD `onlinetime2` BIGINT(20) NOT NULL DEFAULT '0',
ADD `onlinetime3` BIGINT(20) NOT NULL DEFAULT '0',
ADD `onlinetime4` BIGINT(20) NOT NULL DEFAULT '0',
ADD `onlinetime5` BIGINT(20) NOT NULL DEFAULT '0',
ADD `onlinetime6` BIGINT(20) NOT NULL DEFAULT '0',
ADD `onlinetime7` BIGINT(20) NOT NULL DEFAULT '0',
ADD `onlinetimeall` BIGINT(20) NOT NULL DEFAULT '0';
]]--
-- after that execute: --
--[[
UPDATE `znote_players` AS `z` INNER JOIN `players` AS `p` ON `p`.`id`=`z`.`player_id` SET `z`.`exphist_lastexp`=`p`.`experience`;
]]--
local globalevent = GlobalEvent("PowerGamers")
function globalevent.onThink(...)
if tonumber(os.date("%d")) ~= getEternalStorage(23856) then
setEternalStorage(23856, (tonumber(os.date("%d"))))
db.query("UPDATE `znote_players` SET `onlinetime7`=`onlinetime6`, `onlinetime6`=`onlinetime5`, `onlinetime5`=`onlinetime4`, `onlinetime4`=`onlinetime3`, `onlinetime3`=`onlinetime2`, `onlinetime2`=`onlinetime1`, `onlinetime1`=`onlinetimetoday`, `onlinetimetoday`=0;")
db.query("UPDATE `znote_players` `z` INNER JOIN `players` `p` ON `p`.`id`=`z`.`player_id` SET `z`.`exphist7`=`z`.`exphist6`, `z`.`exphist6`=`z`.`exphist5`, `z`.`exphist5`=`z`.`exphist4`, `z`.`exphist4`=`z`.`exphist3`, `z`.`exphist3`=`z`.`exphist2`, `z`.`exphist2`=`z`.`exphist1`, `z`.`exphist1`=`p`.`experience`-`z`.`exphist_lastexp`, `z`.`exphist_lastexp`=`p`.`experience`;")
end
db.query("UPDATE `znote_players` SET `onlinetimetoday` = `onlinetimetoday` + 60, `onlinetimeall` = `onlinetimeall` + 60 WHERE `player_id` IN (SELECT `player_id` FROM `players_online` WHERE `players_online`.`player_id` = `znote_players`.`player_id`)")
return true
end
globalevent:interval(60000)
globalevent:register()

View File

@ -0,0 +1,21 @@
local talkaction = TalkAction("!report")
function talkaction.onSay(player)
local storage = 6708 -- You can change the storage if its already in use
local delaytime = 30 -- Exhaust In Seconds.
if param == '' then
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "Command param required.")
return true
end
if player:getStorageValue(storage) <= os.time() then
player:sendTextMessage(MESSAGE_INFO_DESCR, "Your report has been received successfully!")
db.query("INSERT INTO `znote_player_reports` (`id` ,`name` ,`posx` ,`posy` ,`posz` ,`report_description` ,`date`)VALUES (NULL , " .. db.escapeString(player:getName()) .. ", '" .. player:getPosition().x .. "', '" .. player:getPosition().y .. "', '" .. player:getPosition().z .. "', " .. db.escapeString(param) .. ", '" .. os.time() .. "')")
player:setStorageValue(storage, os.time() + delaytime)
else
player:sendTextMessage(MESSAGE_STATUS_WARNING, "You have to wait " .. player:getStorageValue(storage) - os.time() .. " seconds to report again.")
end
return true
end
talkaction:separator(" ")
talkaction:register()

View File

@ -0,0 +1,158 @@
local globalevent = GlobalEvent("ShopSystemGlobal")
function globalevent.onThink(...)
local orderQuery = db.storeQuery([[
SELECT
MIN(`po`.`player_id`) AS `player_id`,
`shop`.`id`,
`shop`.`type`,
`shop`.`itemid`,
`shop`.`count`
FROM `players_online` AS `po`
INNER JOIN `players` AS `p`
ON `po`.`player_id` = `p`.`id`
INNER JOIN `znote_shop_orders` AS `shop`
ON `p`.`account_id` = `shop`.`account_id`
WHERE `shop`.`type` IN(1,5,6,7)
GROUP BY `shop`.`id`
]])
-- Detect if we got any results
if orderQuery ~= false then
local type_desc = {
"itemids",
"pending premium (skip)",
"pending gender change (skip)",
"pending character name change (skip)",
"Outfit and addons",
"Mounts",
"Instant house purchase"
}
repeat
local player_id = result.getNumber(orderQuery, 'player_id')
local orderId = result.getNumber(orderQuery, 'id')
local orderType = result.getNumber(orderQuery, 'type')
local orderItemId = result.getNumber(orderQuery, 'itemid')
local orderCount = result.getNumber(orderQuery, 'count')
local served = false
local player = Player(player_id)
if player ~= nil then
local description = "Unknown or custom type"
if type_desc[orderType] ~= nil then
description = type_desc[orderType]
end
print("Processing type "..orderType..": ".. description)
print("Processing shop order for: [".. player:getName() .."] type "..orderType..": ".. description)
local tile = Tile(player:getPosition())
if tile ~= nil and tile:hasFlag(TILESTATE_PROTECTIONZONE) then
-- ORDER TYPE 1 (Regular item shop products)
if orderType == 1 then
served = true
local itemType = ItemType(orderItemId)
-- Get weight
if player:getFreeCapacity() >= itemType:getWeight(orderCount) then
local backpack = player:getSlotItem(CONST_SLOT_BACKPACK)
-- variable = (condition) and (return if true) or (return if false)
local needslots = itemType:isStackable() and math.floor(orderCount / 100) + 1 or orderCount
if backpack ~= nil and backpack:getEmptySlots(false) >= needslots then
db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. orderId .. ";")
player:addItem(orderItemId, orderCount)
player:sendTextMessage(MESSAGE_INFO_DESCR, "Congratulations! You have received " .. orderCount .. "x " .. ItemType(orderItemId):getName() .. "!")
print("Process complete. [".. player:getName() .."] has received " .. orderCount .. "x " .. ItemType(orderItemId):getName() .. ".")
else -- not enough slots
player:sendTextMessage(MESSAGE_STATUS_WARNING, "Your main backpack is full. You need to free up "..needslots.." available slots to get " .. orderCount .. " " .. ItemType(orderItemId):getName() .. "!")
print("Process canceled. [".. player:getName() .."] need more space in his backpack to get " .. orderCount .. "x " .. ItemType(orderItemId):getName() .. ".")
end
else -- not enough cap
player:sendTextMessage(MESSAGE_STATUS_WARNING, "You need more CAP to carry this order!")
print("Process canceled. [".. player:getName() .."] need more cap to carry " .. orderCount .. "x " .. ItemType(orderItemId):getName() .. ".")
end
end
-- ORDER TYPE 5 (Outfit and addon)
if orderType == 5 then
served = true
local itemid = orderItemId
local outfits = {}
if itemid > 1000 then
local first = math.floor(itemid/1000)
table.insert(outfits, first)
itemid = itemid - (first * 1000)
end
table.insert(outfits, itemid)
for _, outfitId in pairs(outfits) do
-- Make sure player don't already have this outfit and addon
if not player:hasOutfit(outfitId, orderCount) then
db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. orderId .. ";")
player:addOutfit(outfitId)
player:addOutfitAddon(outfitId, orderCount)
player:sendTextMessage(MESSAGE_INFO_DESCR, "Congratulations! You have received a new outfit!")
print("Process complete. [".. player:getName() .."] has received outfit: ["..outfitId.."] with addon: ["..orderCount.."]")
else -- Already has outfit
player:sendTextMessage(MESSAGE_STATUS_WARNING, "You already have this outfit and addon!")
print("Process canceled. [".. player:getName() .."] already have outfit: ["..outfitId.."] with addon: ["..orderCount.."].")
end
end
end
-- ORDER TYPE 6 (Mounts)
if orderType == 6 then
served = true
-- Make sure player don't already have this outfit and addon
if not player:hasMount(orderItemId) then
db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. orderId .. ";")
player:addMount(orderItemId)
player:sendTextMessage(MESSAGE_INFO_DESCR, "Congratulations! You have received a new mount!")
print("Process complete. [".. player:getName() .."] has received mount: ["..orderItemId.."]")
else -- Already has mount
player:sendTextMessage(MESSAGE_STATUS_WARNING, "You already have this mount!")
print("Process canceled. [".. player:getName() .."] already have mount: ["..orderItemId.."].")
end
end
-- ORDER TYPE 7 (Direct house purchase)
if orderType == 7 then
served = true
local house = House(orderItemId)
-- Logged in player is not necessarily the player that bough the house. So we need to load player from db.
local buyerQuery = db.storeQuery("SELECT `name` FROM `players` WHERE `id` = "..orderCount.." LIMIT 1")
if buyerQuery ~= false then
local buyerName = result.getString(buyerQuery, "name")
result.free(buyerQuery)
if house then
db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. orderId .. ";")
house:setOwnerGuid(orderCount)
player:sendTextMessage(MESSAGE_INFO_DESCR, "You have successfully bought the house "..house:getName().." on "..buyerName..", be sure to have the money for the rent in the bank.")
print("Process complete. [".. buyerName .."] has received house: ["..house:getName().."]")
else
print("Process canceled. Failed to load house with ID: "..orderItemId)
end
else
print("Process canceled. Failed to load player with ID: "..orderCount)
end
end
if not served then -- If this order hasn't been processed yet (missing type handling?)
print("Znote shop: Type ["..orderType.."] not properly processed. Missing Lua code?")
end
else -- Not in protection zone
player:sendTextMessage(MESSAGE_INFO_DESCR, 'You have a pending shop order, please enter protection zone.')
print("Skipped one shop order. Reason: Player: [".. player:getName() .."] is not inside protection zone.")
end
else -- player not logged in
print("Skipped one shop order. Reason: Player with id [".. player_id .."] is not online.")
end
until not result.next(orderQuery)
result.free(orderQuery)
end
return true
end
globalevent:interval(30000)
globalevent:register()

View File

@ -0,0 +1,135 @@
local talkaction = TalkAction("!shop")
function talkaction.onSay(player)
local storage = 54073 -- Make sure to select non-used storage. This is used to prevent SQL load attacks.
local cooldown = 15 -- in seconds.
if player:getStorageValue(storage) <= os.time() then
player:setStorageValue(storage, os.time() + cooldown)
local type_desc = {
"itemids",
"pending premium (skip)",
"pending gender change (skip)",
"pending character name change (skip)",
"Outfit and addons",
"Mounts",
"Instant house purchase"
}
print("Player: " .. player:getName() .. " triggered !shop talkaction.")
-- Create the query
local orderQuery = db.storeQuery("SELECT `id`, `type`, `itemid`, `count` FROM `znote_shop_orders` WHERE `account_id` = " .. player:getAccountId() .. ";")
local served = false
-- Detect if we got any results
if orderQuery ~= false then
repeat
-- Fetch order values
local q_id = result.getNumber(orderQuery, "id")
local q_type = result.getNumber(orderQuery, "type")
local q_itemid = result.getNumber(orderQuery, "itemid")
local q_count = result.getNumber(orderQuery, "count")
local description = "Unknown or custom type"
if type_desc[q_type] ~= nil then
description = type_desc[q_type]
end
print("Processing type "..q_type..": ".. description)
-- ORDER TYPE 1 (Regular item shop products)
if q_type == 1 then
served = true
-- Get weight
if player:getFreeCapacity() >= ItemType(q_itemid):getWeight(q_count) then
db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. q_id .. ";")
player:addItem(q_itemid, q_count)
player:sendTextMessage(MESSAGE_INFO_DESCR, "Congratulations! You have received " .. q_count .. " x " .. ItemType(q_itemid):getName() .. "!")
else
player:sendTextMessage(MESSAGE_STATUS_WARNING, "Need more CAP!")
end
end
-- ORDER TYPE 5 (Outfit and addon)
if q_type == 5 then
served = true
local itemid = q_itemid
local outfits = {}
if itemid > 1000 then
local first = math.floor(itemid/1000)
table.insert(outfits, first)
itemid = itemid - (first * 1000)
end
table.insert(outfits, itemid)
for _, outfitId in pairs(outfits) do
-- Make sure player don't already have this outfit and addon
if not player:hasOutfit(outfitId, q_count) then
db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. q_id .. ";")
player:addOutfit(outfitId)
player:addOutfitAddon(outfitId, q_count)
player:sendTextMessage(MESSAGE_INFO_DESCR, "Congratulations! You have received a new outfit!")
else
player:sendTextMessage(MESSAGE_STATUS_WARNING, "You already have this outfit and addon!")
end
end
end
-- ORDER TYPE 6 (Mounts)
if q_type == 6 then
served = true
-- Make sure player don't already have this outfit and addon
if not player:hasMount(q_itemid) then
db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. q_id .. ";")
player:addMount(q_itemid)
player:sendTextMessage(MESSAGE_INFO_DESCR, "Congratulations! You have received a new mount!")
else
player:sendTextMessage(MESSAGE_STATUS_WARNING, "You already have this mount!")
end
end
-- ORDER TYPE 7 (Direct house purchase)
if orderType == 7 then
served = true
local house = House(orderItemId)
-- Logged in player is not necessarily the player that bough the house. So we need to load player from db.
local buyerQuery = db.storeQuery("SELECT `name` FROM `players` WHERE `id` = "..orderCount.." LIMIT 1")
if buyerQuery ~= false then
local buyerName = result.getString(buyerQuery, "name")
result.free(buyerQuery)
if house then
db.query("DELETE FROM `znote_shop_orders` WHERE `id` = " .. orderId .. ";")
house:setOwnerGuid(orderCount)
player:sendTextMessage(MESSAGE_INFO_DESCR, "You have successfully bought the house "..house:getName().." on "..buyerName..", be sure to have the money for the rent in the bank.")
print("Process complete. [".. buyerName .."] has received house: ["..house:getName().."]")
end
end
end
-- Add custom order types here
-- Type 1 is for itemids (Already coded here)
-- Type 2 is for premium (Coded on web)
-- Type 3 is for gender change (Coded on web)
-- Type 4 is for character name change (Coded on web)
-- Type 5 is for character outfit and addon (Already coded here)
-- Type 6 is for mounts (Already coded here)
-- Type 7 is for Instant house purchase (Already coded here)
-- So use type 8+ for custom stuff, like etc packages.
-- if q_type == 8 then
-- end
until not result.next(orderQuery)
result.free(orderQuery)
if not served then
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have no orders to process in-game.")
end
else
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have no orders.")
end
else
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Can only be executed once every " .. cooldown .. " seconds. Remaining cooldown: " .. player:getStorageValue(storage) - os.time())
end
return false
end
talkaction:register()

View File

@ -0,0 +1,50 @@
local creatureevent = CreatureEvent("SincOutfit")
-- Sync outfits that player own with Znote AAC
-- So its possible to see which full sets player
-- has in characterprofile.php
znote_outfit_list = {
{ -- Female outfits
136, 137, 138, 139, 140, 141, 142, 147, 148,
149, 150, 155, 156, 157, 158, 252, 269, 270,
279, 288, 324, 329, 336, 366, 431, 433, 464,
466, 471, 513, 514, 542, 575, 578, 618, 620,
632, 635, 636, 664, 666, 683, 694, 696, 698,
724, 732, 745, 749, 759, 845, 852, 874, 885,
900, 973, 975, 1020, 1024, 1043, 1050, 1057,
1070, 1095, 1103, 1128, 1147, 1162, 1174,
1187, 1203, 1205, 1207, 1211, 1246, 1244,
1252, 1271, 1280, 1283, 1289, 1293, 1332
},
{ -- Male outfits
128, 129, 130, 131, 132, 133, 134, 143, 144,
145, 146, 151, 152, 153, 154, 251, 268, 273,
278, 289, 325, 328, 335, 367, 430, 432, 463,
465, 472, 512, 516, 541, 574, 577, 610, 619,
633, 634, 637, 665, 667, 684, 695, 697, 699,
725, 733, 746, 750, 760, 846, 853, 873, 884,
899, 908, 931, 955, 957, 962, 964, 966, 968,
970, 972, 974, 1021, 1023, 1042, 1051, 1056,
1069, 1094, 1102, 1127, 1146, 1161, 1173,
1186, 1202, 1204, 1206, 1210, 1245, 1243,
1251, 1270, 1279, 1282, 1288, 1292, 1331
}
}
function creatureevent.onLogin(player)
-- storage_value + 1000 storages (highest outfit id) must not be used in other script.
-- Must be identical to Znote AAC config.php: $config['EQ_shower'] -> storage_value
local storage_value = 10000
-- Loop through outfits
for _, outfit in pairs(znote_outfit_list[player:getSex() + 1]) do
if player:hasOutfit(outfit,3) then
if player:getStorageValue(storage_value + outfit) ~= 3 then
player:setStorageValue(storage_value + outfit, 3)
end
end
end
return true
end
creatureevent:register()

View File

@ -256,7 +256,7 @@
// TFS 1.x powergamers and top online
// Before enabling powergamers, make sure that you have added Lua files and added the SQL columns to your server db.
// files can be found at LUA folder.
// files can be found at Lua folder.
$config['powergamers'] = array(
'enabled' => true, // Enable or disable page
'limit' => 20, // Number of players that it will show.
@ -607,7 +607,7 @@
'outfits' => true,
// Player storage (storage_value + outfitId)
// used to see if player has outfit.
// see LUA scripts folder for otserv code
// see Lua scripts folder for otserv code
'storage_value' => 10000
);
@ -936,7 +936,7 @@
////////////
/// SHOP ///
////////////
// If useDB is set to true, player can shop in-game as well using Znote LUA shop system plugin.
// If useDB is set to true, player can shop in-game as well using Znote Lua shop system plugin.
$config['shop'] = array(
'enabled' => false,
'loginToView' => false, // Do user need to login to see the shop offers?