diff --git a/config.lua.dist b/config.lua.dist index d667bb48952..a5bb3d73ca5 100644 --- a/config.lua.dist +++ b/config.lua.dist @@ -238,6 +238,7 @@ onlyPremiumAccount = false -- NOTE: randomMonsterSpawn = true, will enable monsters from the same spawn to be randomized between them, thus making a variable hunt -- NOTE: enablePlayerPutItemInAmmoSlot = true, will enable players to put any items on ammo slot, more used in custom shopping system -- NOTE: startStreakLevel will make a reward streak level for new players who never logged in +-- NOTE: if showLootsInBestiary is true, will cause all loots to be shown in the bestiary even if the player has not reached the required number of kills stashMoving = false depotChest = 4 autoLoot = false @@ -255,6 +256,7 @@ lootPouchMaxLimit = 2000 storeInboxMaxLimit = 2000 enablePlayerPutItemInAmmoSlot = false startStreakLevel = 0 +showLootsInBestiary = false -- Teleport summon -- Set to true will never remove the summon @@ -427,6 +429,9 @@ maxDamageReflection = 200 toggleChainSystem = true combatChainDelay = 50 combatChainTargets = 5 +combatChainSkillFormulaAxe = 0.9 +combatChainSkillFormulaClub = 0.7 +combatChainSkillFormulaSword = 1.1 -- Global server Save -- NOTE: globalServerSaveNotifyDuration in minutes diff --git a/data-canary/scripts/actions/other/carpets.lua b/data-canary/scripts/actions/other/carpets.lua deleted file mode 100644 index aaa90026a22..00000000000 --- a/data-canary/scripts/actions/other/carpets.lua +++ /dev/null @@ -1,88 +0,0 @@ -local carpetItems = { - [22737] = 22736, - [22736] = 22737, -- Rift carpet - [23537] = 23536, - [23536] = 23537, -- Void carpet - [23431] = 23453, - [23453] = 23431, -- Yalaharian carpet - [23432] = 23454, - [23454] = 23432, -- White fur carpet - [23433] = 23455, - [23455] = 23433, -- Bamboo mat carpet - [23715] = 23707, - [23707] = 23715, -- Crimson carpet - [23710] = 23716, - [23716] = 23710, -- Azure carpet - [23711] = 23717, - [23717] = 23711, -- Emerald carpet - [23712] = 23718, - [23718] = 23712, -- Light parquet carpet - [23713] = 23719, - [23719] = 23713, -- Dark parquet carpet - [23714] = 23720, - [23720] = 23714, -- Marble floor - [24416] = 24424, - [24424] = 24416, -- Flowery carpet - [24417] = 24425, - [24425] = 24417, -- Colourful Carpet - [24418] = 24426, - [24426] = 24418, -- Striped carpet - [24419] = 24427, - [24427] = 24419, -- Fur carpet - [24420] = 24428, - [24428] = 24420, -- Diamond carpet - [24421] = 24429, - [24429] = 24421, -- Patterned carpet - [24422] = 24430, - [24430] = 24422, -- Night sky carpet - [24423] = 24431, - [24431] = 24423, -- Star carpet - [26114] = 26115, - [26115] = 26114, -- Verdant carpet - [26116] = 26117, - [26117] = 26116, -- Shaggy carpet - [26118] = 26119, - [26119] = 26118, -- Mystic carpet - [26120] = 26121, - [26121] = 26120, -- Stone tile - [26123] = 26122, - [26122] = 26123, -- Wooden plank - [26151] = 26150, - [26150] = 26151, -- Wheat carpet - [26152] = 26153, - [26153] = 26152, -- Crested carpet - [26154] = 26155, - [26155] = 26154, -- Decorated carpet -} - -local carpets = Action() - -function carpets.onUse(player, item, fromPosition, target, toPosition, isHotkey) - local carpet = carpetItems[item.itemid] - if not carpet then - return false - end - local tile = Tile(item:getPosition()) - local carpetStack = 0 - for _, carpetId in pairs(carpetItems) do - carpetStack = carpetStack + tile:getItemCountById(carpetId) - end - if fromPosition.x == CONTAINER_POSITION then - player:sendTextMessage(MESSAGE_FAILURE, "Put the item on the floor first.") - return true - elseif not tile or not tile:getHouse() then - player:sendTextMessage(MESSAGE_FAILURE, "You may use this only inside a house.") - return true - elseif carpetStack > 1 then - player:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) - return true - end - item:transform(carpet) - return true -end - -for index, value in pairs(carpetItems) do - carpets:id(index) -end - -carpets:register() diff --git a/data-canary/scripts/actions/other/die.lua b/data-canary/scripts/actions/other/die.lua deleted file mode 100644 index e7bc7316e9a..00000000000 --- a/data-canary/scripts/actions/other/die.lua +++ /dev/null @@ -1,23 +0,0 @@ -local die = Action() - -function die.onUse(player, item, fromPosition, target, toPosition, isHotkey) - local position = item:getPosition() - local value = math.random(1, 6) - local isInGhostMode = player:isInGhostMode() - - position:sendMagicEffect(CONST_ME_CRAPS, isInGhostMode and player) - - local spectators = Game.getSpectators(position, false, true, 3, 3) - for _, spectator in ipairs(spectators) do - player:say(player:getName() .. " rolled a " .. value .. ".", TALKTYPE_MONSTER_SAY, isInGhostMode, spectator, position) - end - - item:transform(5791 + value) - return true -end - -for items = 5792, 5797 do - die:id(items) -end - -die:register() diff --git a/data-canary/scripts/actions/other/food.lua b/data-canary/scripts/actions/other/food.lua deleted file mode 100644 index fcf05eefd52..00000000000 --- a/data-canary/scripts/actions/other/food.lua +++ /dev/null @@ -1,132 +0,0 @@ -local setting = { - --[itemid] = {foodvalue, saytext} - [169] = { 9, "Urgh." }, -- scarab cheese - [836] = { 4, "Crunch." }, -- walnut - [841] = { 4, "Crunch." }, -- peanut - [901] = { 60, "Munch." }, -- marlin - [3250] = { 5, "Crunch." }, -- carrot - [3577] = { 15, "Munch." }, -- meat - [3578] = { 12, "Munch." }, -- fish - [3579] = { 10, "Mmmm." }, -- salmon - [3580] = { 17, "Munch." }, -- northern pike - [3581] = { 4, "Gulp." }, -- shrimp - [3582] = { 30, "Chomp." }, -- ham - [3583] = { 60, "Chomp." }, -- dragon ham - [3584] = { 5, "Yum." }, -- pear - [3585] = { 6, "Yum." }, -- red apple - [3586] = { 13, "Yum." }, -- orange - [3587] = { 8, "Yum." }, -- banana - [3588] = { 1, "Yum." }, -- blueberry - [3589] = { 18, "Slurp." }, -- coconut - [3590] = { 1, "Yum." }, -- cherry - [3591] = { 2, "Yum." }, -- strawberry - [3592] = { 9, "Yum." }, -- grapes - [3593] = { 20, "Yum." }, -- melon - [3594] = { 17, "Munch." }, -- pumpkin - [3595] = { 5, "Crunch." }, -- carrot - [3596] = { 6, "Munch." }, -- tomato - [3597] = { 9, "Crunch." }, -- corncob - [3598] = { 2, "Crunch." }, -- cookie - [3599] = { 2, "Munch." }, -- candy cane - [3600] = { 10, "Crunch." }, -- bread - [3601] = { 3, "Crunch." }, -- roll - [3602] = { 8, "Crunch." }, -- brown bread - [3606] = { 6, "Gulp." }, -- egg - [3607] = { 9, "Smack." }, -- cheese - [3723] = { 9, "Munch." }, -- white mushroom - [3724] = { 4, "Munch." }, -- red mushroom - [3725] = { 22, "Munch." }, -- brown mushroom - [3726] = { 30, "Munch." }, -- orange mushroom - [3727] = { 9, "Munch." }, -- wood mushroom - [3728] = { 6, "Munch." }, -- dark mushroom - [3729] = { 12, "Munch." }, -- some mushrooms - [3730] = { 3, "Munch." }, -- some mushrooms - [3731] = { 36, "Munch." }, -- fire mushroom - [3732] = { 5, "Munch." }, -- green mushroom - [5096] = { 4, "Yum." }, -- mango - [6125] = { 8, "Gulp." }, -- tortoise egg - [6277] = { 10, "Mmmm." }, -- cake - [6278] = { 15, "Mmmm." }, -- decorated cake - [6392] = { 12, "Mmmm." }, -- valentine's cake - [6393] = { 15, "Mmmm." }, -- cream cake - [6500] = { 20, "Mmmm." }, -- gingerbread man - [6541] = { 6, "Gulp." }, -- coloured egg (yellow) - [6542] = { 6, "Gulp." }, -- coloured egg (red) - [6543] = { 6, "Gulp." }, -- coloured egg (blue) - [6544] = { 6, "Gulp." }, -- coloured egg (green) - [6545] = { 6, "Gulp." }, -- coloured egg (purple) - [6569] = { 1, "Mmmm." }, -- candy - [6574] = { 5, "Mmmm." }, -- bar of chocolate - [7158] = { 15, "Munch." }, -- rainbow trout - [7159] = { 13, "Munch." }, -- green perch - [7372] = { 2, "Yum." }, -- ice cream cone (crispy chocolate chips) - [7373] = { 2, "Yum." }, -- ice cream cone (velvet vanilla) - [7374] = { 2, "Yum." }, -- ice cream cone (sweet strawberry) - [7375] = { 2, "Yum." }, -- ice cream cone (chilly cherry) - [7376] = { 2, "Yum." }, -- ice cream cone (mellow melon) - [7377] = { 2, "Yum." }, -- ice cream cone (blue-barian) - [8010] = { 10, "Gulp." }, -- potato - [8011] = { 5, "Yum." }, -- plum - [8012] = { 1, "Yum." }, -- raspberry - [8013] = { 1, "Urgh." }, -- lemon - [8014] = { 7, "Munch." }, -- cucumber - [8015] = { 5, "Crunch." }, -- onion - [8016] = { 1, "Gulp." }, -- jalapeƱo pepper - [8017] = { 5, "Munch." }, -- beetroot - [8018] = { 11, "Yum." }, -- chocolate cake - [8019] = { 7, "Slurp." }, -- yummy gummy worm - [8197] = { 5, "Crunch." }, -- bulb of garlic - [9083] = { 0, "Slurp." }, -- banana chocolate shake - [9537] = { 0, "Your head begins to feel better." }, -- headache pill - [10329] = { 15, "Yum." }, -- rice ball - [10453] = { 3, "Urgh." }, -- terramite eggs - [10219] = { 10, "Mmmm." }, -- crocodile steak - [11459] = { 20, "Yum." }, -- pineapple - [11460] = { 10, "Munch." }, -- aubergine - [11461] = { 8, "Crunch." }, -- broccoli - [11462] = { 9, "Crunch." }, -- cauliflower - [11681] = { 55, "Gulp." }, -- ectoplasmic sushi - [11682] = { 18, "Yum." }, -- dragonfruit - [11683] = { 2, "Munch." }, -- peas - [12310] = { 20, "Crunch." }, -- haunch of boar - [13992] = { 55, "Munch." }, -- sandfish - [14084] = { 14, "Urgh." }, -- larvae - [14085] = { 15, "Munch." }, -- deepling filet - [14681] = { 60, "Mmmm." }, -- anniversary cake - [16103] = { 33, "Munch." }, -- mushroom pie - [17457] = { 10, "Urgh." }, -- insectoid eggs - [17820] = { 15, "Smack." }, -- soft cheese - [17821] = { 12, "Smack." }, -- rat cheese - [22185] = { 12, "Yum." }, -- prickly pear - [22187] = { 60, "Chomp." }, -- roasted meat - [23535] = { 30, "Mmmm." }, -- energy bar - [23545] = { 18, "Mmmm." }, -- energy drink -} - -local food = Action() - -function food.onUse(player, item, fromPosition, target, toPosition, isHotkey) - local itemFood = setting[item.itemid] - if not itemFood then - return false - end - - local condition = player:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) - if condition and math.floor(condition:getTicks() / 1000 + (itemFood[1] * 12)) >= 1200 then - player:sendTextMessage(MESSAGE_FAILURE, "You are full.") - return true - end - - player:feed(itemFood[1] * 12) - player:say(itemFood[2], TALKTYPE_MONSTER_SAY) - item:remove(1) - player:updateSupplyTracker(item) - player:getPosition():sendSingleSoundEffect(SOUND_EFFECT_TYPE_ACTION_EAT, player:isInGhostMode() and nil or player) - return true -end - -for index, value in pairs(setting) do - food:id(index) -end - -food:register() diff --git a/data-canary/scripts/creaturescripts/advance_save.lua b/data-canary/scripts/creaturescripts/advance_save.lua deleted file mode 100644 index 8bd6fd2fd06..00000000000 --- a/data-canary/scripts/creaturescripts/advance_save.lua +++ /dev/null @@ -1,32 +0,0 @@ -local config = { - heal = true, - save = true, - effect = false, -} - -local advanceSave = CreatureEvent("AdvanceSave") - -function advanceSave.onAdvance(player, skill, oldLevel, newLevel) - if skill ~= SKILL_LEVEL or newLevel <= oldLevel then - return true - end - - if config.effect then - player:getPosition():sendMagicEffect(math.random(CONST_ME_FIREWORK_YELLOW, CONST_ME_FIREWORK_BLUE)) - player:say("LEVEL UP!", TALKTYPE_MONSTER_SAY) - end - - if config.heal then - player:addHealth(player:getMaxHealth()) - end - - if config.save then - player:save() - end - - player:getFinalLowLevelBonus() - - return true -end - -advanceSave:register() diff --git a/data-canary/scripts/creaturescripts/logout.lua b/data-canary/scripts/creaturescripts/logout.lua deleted file mode 100644 index 598a55878d2..00000000000 --- a/data-canary/scripts/creaturescripts/logout.lua +++ /dev/null @@ -1,17 +0,0 @@ -local logout = CreatureEvent("PlayerLogout") - -function logout.onLogout(player) - local playerId = player:getId() - if _G.NextUseStaminaTime[playerId] then - _G.NextUseStaminaTime[playerId] = nil - end - - if _G.OnExerciseTraining[playerId] then - stopEvent(_G.OnExerciseTraining[playerId].event) - _G.OnExerciseTraining[playerId] = nil - player:setTraining(false) - end - return true -end - -logout:register() diff --git a/data-canary/scripts/creaturescripts/regenerate_stamina.lua b/data-canary/scripts/creaturescripts/regenerate_stamina.lua deleted file mode 100644 index cc112ce6958..00000000000 --- a/data-canary/scripts/creaturescripts/regenerate_stamina.lua +++ /dev/null @@ -1,31 +0,0 @@ -local regenerateStamina = CreatureEvent("Regenerate Stamina") - -function regenerateStamina.onLogin(player) - if not configManager.getBoolean(configKeys.STAMINA_SYSTEM) then - return true - end - - local lastLogout = player:getLastLogout() - local offlineTime = lastLogout ~= 0 and math.min(os.time() - lastLogout, 86400 * 21) or 0 - offlineTime = offlineTime - 600 - - if offlineTime < 180 then - return true - end - - local staminaMinutes = player:getStamina() - local maxNormalStaminaRegen = 2400 - math.min(2400, staminaMinutes) - - local regainStaminaMinutes = offlineTime / 180 - if regainStaminaMinutes > maxNormalStaminaRegen then - local happyHourStaminaRegen = (offlineTime - (maxNormalStaminaRegen * 180)) / 600 - staminaMinutes = math.min(2520, math.max(2400, staminaMinutes) + happyHourStaminaRegen) - else - staminaMinutes = staminaMinutes + regainStaminaMinutes - end - - player:setStamina(staminaMinutes) - return true -end - -regenerateStamina:register() diff --git a/data-otservbr-global/lib/core/storages.lua b/data-otservbr-global/lib/core/storages.lua index 8dd5ff45a61..69f1d7f7948 100644 --- a/data-otservbr-global/lib/core/storages.lua +++ b/data-otservbr-global/lib/core/storages.lua @@ -103,7 +103,7 @@ Storage = { Factions = 30024, -- unused TrainerRoom = 30027, -- unused NpcSpawn = 30028, - ExerciseDummyExhaust = 30029, + -- unused ExerciseDummyExhaust = 30029, SamsOldBackpack = 30030, SamsOldBackpackDoor = 30031, StrawberryCupcake = 30032, @@ -2113,7 +2113,7 @@ Storage = { BloodBrothers = { QuestLine = 41901, Mission01 = 41902, - GarlicBread = 41903, + -- unused GarlicBread = 41903, Mission02 = 41904, Cookies = { Serafin = 41905, diff --git a/data-otservbr-global/lib/others/vip_system.lua b/data-otservbr-global/lib/others/vip_system.lua index 6ca6de7d204..5a393157c8c 100644 --- a/data-otservbr-global/lib/others/vip_system.lua +++ b/data-otservbr-global/lib/others/vip_system.lua @@ -3,7 +3,7 @@ local config = { activationMessageType = MESSAGE_EVENT_ADVANCE, expirationMessage = "Your VIP days ran out.", - expirationMessageType = MESSAGE_ADMINISTRADOR, + expirationMessageType = MESSAGE_ADMINISTRATOR, outfits = {}, mounts = {}, diff --git a/data-otservbr-global/migrations/41.lua b/data-otservbr-global/migrations/41.lua index 179ac18b574..15eb1d88e99 100644 --- a/data-otservbr-global/migrations/41.lua +++ b/data-otservbr-global/migrations/41.lua @@ -3,8 +3,8 @@ function onUpdateDatabase() db.query([[ ALTER TABLE `players` - MODIFY `xpboost_stamina` smallint(5) UNSIGNED DEFAULT NULL, - MODIFY `xpboost_value` tinyint(4) UNSIGNED DEFAULT NULL + MODIFY `xpboost_stamina` smallint(5) UNSIGNED DEFAULT NULL, + MODIFY `xpboost_value` tinyint(4) UNSIGNED DEFAULT NULL ]]) return true diff --git a/data-otservbr-global/migrations/43.lua b/data-otservbr-global/migrations/43.lua index 86a6d8ffec1..1464703c96e 100644 --- a/data-otservbr-global/migrations/43.lua +++ b/data-otservbr-global/migrations/43.lua @@ -1,3 +1,12 @@ function onUpdateDatabase() - return false -- true = There are others migrations file | false = this is the last migration file + logger.info("Updating database to version 43 (feat frags_limit, payment and duration_days in guild wars)") + + db.query([[ + ALTER TABLE `guild_wars` + ADD `frags_limit` smallint(4) UNSIGNED NOT NULL DEFAULT '0', + ADD `payment` bigint(13) UNSIGNED NOT NULL DEFAULT '0', + ADD `duration_days` tinyint(3) UNSIGNED NOT NULL DEFAULT '0' + ]]) + + return true end diff --git a/data-otservbr-global/migrations/44.lua b/data-otservbr-global/migrations/44.lua new file mode 100644 index 00000000000..86a6d8ffec1 --- /dev/null +++ b/data-otservbr-global/migrations/44.lua @@ -0,0 +1,3 @@ +function onUpdateDatabase() + return false -- true = There are others migrations file | false = this is the last migration file +end diff --git a/data-otservbr-global/monster/quests/the_secret_library/bosses/grand_master_oberon_functions.lua b/data-otservbr-global/monster/quests/the_secret_library/bosses/grand_master_oberon_functions.lua index 86714879320..af9c6f0218a 100644 --- a/data-otservbr-global/monster/quests/the_secret_library/bosses/grand_master_oberon_functions.lua +++ b/data-otservbr-global/monster/quests/the_secret_library/bosses/grand_master_oberon_functions.lua @@ -24,7 +24,7 @@ GrandMasterOberonResponses = { [6] = { msg = "Excuse me but I still do not get the message!", msg2 = oberonOthersMessages[2] }, [7] = { msg = "Dare strike up a Minnesang and you will receive your last accolade!", msg2 = oberonOthersMessages[1] }, [8] = { msg = "Then why are we fighting alone right now?", msg2 = oberonOthersMessages[2] }, - [9] = { msg = "SEHWO ASIMO, TOLIDO ESD", msg2 = oberonOthersMessages[2] }, + [9] = { msg = "SEHWO ASIMO, TOLIDO ESD!", msg2 = oberonOthersMessages[2] }, } GrandMasterOberonConfig = { diff --git a/data-otservbr-global/npc/julius.lua b/data-otservbr-global/npc/julius.lua index ac3c660a29b..47e8e123760 100644 --- a/data-otservbr-global/npc/julius.lua +++ b/data-otservbr-global/npc/julius.lua @@ -83,7 +83,6 @@ local function creatureSayCallback(npc, creature, type, message) end elseif player:getStorageValue(BloodBrothers.Mission01) == 3 then npcHandler:say("Let me check - yes indeed, there's garlic in it. Now eat one, in front of my eyes. Right now! Say '{aaah}' when you've chewed it all down so that I can see you're not hiding it!", npc, creature) - player:setStorageValue(BloodBrothers.GarlicBread, 0) npcHandler:setTopic(playerId, 4) elseif player:getStorageValue(BloodBrothers.Mission01) == 4 and player:getStorageValue(BloodBrothers.Mission02) < 0 then npcHandler:say("So, are you ready for your first real task?", npc, creature) @@ -164,7 +163,7 @@ local function creatureSayCallback(npc, creature, type, message) end end elseif MsgContains(message, "aaah") then - if npcHandler:getTopic(playerId) == 4 and player:getStorageValue(BloodBrothers.GarlicBread) == 1 then + if npcHandler:getTopic(playerId) == 4 and player:removeItem(8194, 1) then npcHandler:say("Very well. I think I can trust you now. Sorry that I had to put you through this embarassing procedure, but I'm sure you understand. So, are you ready for your first real task?", npc, creature) player:setStorageValue(BloodBrothers.Mission01, 4) npcHandler:setTopic(playerId, 5) diff --git a/data-otservbr-global/scripts/actions/other/dice.lua b/data-otservbr-global/scripts/actions/other/dice.lua deleted file mode 100644 index bd0c6c8f31a..00000000000 --- a/data-otservbr-global/scripts/actions/other/dice.lua +++ /dev/null @@ -1,18 +0,0 @@ -local dice = Action() - -function dice.onUse(player, item, fromPosition, target, toPosition, isHotkey) - local dicePosition = item:getPosition() - local value = math.random(6) - local isInGhostMode = player:isInGhostMode() - - dicePosition:sendMagicEffect(CONST_ME_CRAPS, isInGhostMode and player) - local spectators = Game.getSpectators(dicePosition, false, true, 3, 3) - for i = 1, #spectators do - player:say(player:getName() .. " rolled a " .. value .. ".", TALKTYPE_MONSTER_SAY, isInGhostMode, spectators[i], dicePosition) - end - item:transform(5791 + value) - return true -end - -dice:id(5792, 5793, 5794, 5795, 5796, 5797) -dice:register() diff --git a/data-otservbr-global/scripts/actions/other/voodoo_doll.lua b/data-otservbr-global/scripts/actions/other/voodoo_doll.lua deleted file mode 100644 index 1b77081ee1c..00000000000 --- a/data-otservbr-global/scripts/actions/other/voodoo_doll.lua +++ /dev/null @@ -1,21 +0,0 @@ -local voodooDoll = Action() - -function voodooDoll.onUse(player, item, fromPosition, target, toPosition, isHotkey) - if target.itemid ~= 1 or target.type ~= THING_TYPE_PLAYER then - return false - end - - local text = "" - if math.random(100) <= 5 then - text = "You concentrate on your victim and hit the needle in the doll." - player:addAchievement("Dark Voodoo Priest") - toPosition:sendMagicEffect(CONST_ME_DRAWBLOOD, player) - else - text = "You concentrate on your victim, hit the needle in the doll.......but nothing happens." - end - player:say(text, TALKTYPE_MONSTER_SAY, false, player) - return true -end - -voodooDoll:id(3002) -voodooDoll:register() diff --git a/data-otservbr-global/scripts/actions/rookgaard/rapier_quest.lua b/data-otservbr-global/scripts/actions/rookgaard/rapier_quest.lua new file mode 100644 index 00000000000..20e6697d2f7 --- /dev/null +++ b/data-otservbr-global/scripts/actions/rookgaard/rapier_quest.lua @@ -0,0 +1,15 @@ +local rapierQuest = Action() + +function rapierQuest.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local rewardId = 3272 + if not player:canGetReward(rewardId, "rapier") then + return true + end + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a rapier.") + player:addItem(rewardId, 1) + player:questKV("rapier"):set("completed", true) + return true +end + +rapierQuest:uid(14042) +rapierQuest:register() diff --git a/data-otservbr-global/scripts/creaturescripts/others/advance_save.lua b/data-otservbr-global/scripts/creaturescripts/others/advance_save.lua deleted file mode 100644 index 8bd6fd2fd06..00000000000 --- a/data-otservbr-global/scripts/creaturescripts/others/advance_save.lua +++ /dev/null @@ -1,32 +0,0 @@ -local config = { - heal = true, - save = true, - effect = false, -} - -local advanceSave = CreatureEvent("AdvanceSave") - -function advanceSave.onAdvance(player, skill, oldLevel, newLevel) - if skill ~= SKILL_LEVEL or newLevel <= oldLevel then - return true - end - - if config.effect then - player:getPosition():sendMagicEffect(math.random(CONST_ME_FIREWORK_YELLOW, CONST_ME_FIREWORK_BLUE)) - player:say("LEVEL UP!", TALKTYPE_MONSTER_SAY) - end - - if config.heal then - player:addHealth(player:getMaxHealth()) - end - - if config.save then - player:save() - end - - player:getFinalLowLevelBonus() - - return true -end - -advanceSave:register() diff --git a/data-otservbr-global/scripts/creaturescripts/others/modal_window_helper.lua b/data-otservbr-global/scripts/creaturescripts/others/modal_window_helper.lua deleted file mode 100644 index d2651af1e69..00000000000 --- a/data-otservbr-global/scripts/creaturescripts/others/modal_window_helper.lua +++ /dev/null @@ -1,35 +0,0 @@ -local creatureEvent = CreatureEvent("modalWindowHelper") - -function creatureEvent.onModalWindow(player, modalWindowId, buttonId, choiceId) - local playerId = player:getId() - local modalWindows = ModalWindows[playerId] - if not modalWindows then - return true - end - - local modalWindow = modalWindows[modalWindowId] - if not modalWindow then - return true - end - - local button = modalWindow.buttons[buttonId] or {} - local choice = modalWindow.choices[choiceId] or {} - if button.callback then - button.callback(player, button, choice) - elseif choice.callback then - choice.callback(player, button, choice) - elseif modalWindow.defaultCallback then - modalWindow.defaultCallback(player, button, choice) - end - - modalWindow.using = modalWindow.using - 1 - if modalWindow.using == 0 then - modalWindows[modalWindowId] = nil - if not next(modalWindows) then - ModalWindows[playerId] = nil - end - end - return true -end - -creatureEvent:register() diff --git a/data-otservbr-global/scripts/creaturescripts/others/player_death.lua b/data-otservbr-global/scripts/creaturescripts/others/player_death.lua index 9e8bfbeca34..b848235ebae 100644 --- a/data-otservbr-global/scripts/creaturescripts/others/player_death.lua +++ b/data-otservbr-global/scripts/creaturescripts/others/player_death.lua @@ -84,24 +84,52 @@ function playerDeath.onDeath(player, corpse, killer, mostDamageKiller, unjustifi if byPlayer == 1 then local targetGuild = player:getGuild() - targetGuild = targetGuild and targetGuild:getId() or 0 - if targetGuild ~= 0 then + local targetGuildId = targetGuild and targetGuild:getId() or 0 + if targetGuildId ~= 0 then local killerGuild = killer:getGuild() - killerGuild = killerGuild and killerGuild:getId() or 0 - if killerGuild ~= 0 and targetGuild ~= killerGuild and isInWar(player:getId(), killer.uid) then + local killerGuildId = killerGuild and killerGuild:getId() or 0 + if killerGuildId ~= 0 and targetGuildId ~= killerGuildId and isInWar(player:getId(), killer:getId()) then local warId = false resultId = db.storeQuery("SELECT `id` FROM `guild_wars` WHERE `status` = 1 AND \z - ((`guild1` = " .. killerGuild .. " AND `guild2` = " .. targetGuild .. ") OR \z - (`guild1` = " .. targetGuild .. " AND `guild2` = " .. killerGuild .. "))") - if resultId ~= false then + ((`guild1` = " .. killerGuildId .. " AND `guild2` = " .. targetGuildId .. ") OR \z + (`guild1` = " .. targetGuildId .. " AND `guild2` = " .. killerGuildId .. "))") + if resultId then warId = Result.getNumber(resultId, "id") Result.free(resultId) end - if warId ~= false then + if warId then + local playerName = player:getName() db.asyncQuery("INSERT INTO `guildwar_kills` (`killer`, `target`, `killerguild`, `targetguild`, `time`, `warid`) \z - VALUES (" .. db.escapeString(killerName) .. ", " .. db.escapeString(player:getName()) .. ", " .. killerGuild .. ", \z - " .. targetGuild .. ", " .. os.time() .. ", " .. warId .. ")") + VALUES (" .. db.escapeString(killerName) .. ", " .. db.escapeString(playerName) .. ", " .. killerGuildId .. ", \z + " .. targetGuildId .. ", " .. os.time() .. ", " .. warId .. ")") + + resultId = db.storeQuery("SELECT `guild_wars`.`id`, `guild_wars`.`frags_limit`, (SELECT COUNT(1) FROM `guildwar_kills` \z + WHERE `guildwar_kills`.`warid` = `guild_wars`.`id` AND `guildwar_kills`.`killerguild` = `guild_wars`.`guild1`) AS guild1_kills, \z + (SELECT COUNT(1) FROM `guildwar_kills` WHERE `guildwar_kills`.`warid` = `guild_wars`.`id` AND `guildwar_kills`.`killerguild` = `guild_wars`.`guild2`) AS guild2_kills \z + FROM `guild_wars` WHERE (`guild1` = " .. killerGuildId .. " OR `guild2` = " .. killerGuildId .. ") 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 frags_limit = Result.getNumber(resultId, "frags_limit") + Result.free(resultId) + + local members = killerGuild:getMembersOnline() + for i = 1, #members do + members[i]:sendChannelMessage(members[i], string.format("%s was killed by %s. The new score is: %s %d:%d %s (frags limit: %d)", playerName, killerName, targetGuild:getName(), guild1_kills, guild2_kills, killerGuild:getName(), frags_limit), TALKTYPE_CHANNEL_R1, CHANNEL_GUILD) + end + + local enemyMembers = targetGuild:getMembersOnline() + for i = 1, #enemyMembers do + enemyMembers[i]:sendChannelMessage(enemyMembers[i], string.format("%s was killed by %s. The new score is: %s %d:%d %s (frags limit: %d)", playerName, killerName, targetGuild:getName(), guild1_kills, guild2_kills, killerGuild:getName(), frags_limit), TALKTYPE_CHANNEL_R1, CHANNEL_GUILD) + end + + if guild1_kills >= frags_limit or guild2_kills >= frags_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.", killerGuild:getName(), targetGuild:getName())) + end + end end end end diff --git a/data-otservbr-global/scripts/globalevents/others/guild_war.lua b/data-otservbr-global/scripts/globalevents/others/guild_war.lua index f34828b1fa7..41238755494 100644 --- a/data-otservbr-global/scripts/globalevents/others/guild_war.lua +++ b/data-otservbr-global/scripts/globalevents/others/guild_war.lua @@ -1,9 +1,10 @@ local guildWar = GlobalEvent("guildwar") + function guildWar.onThink(interval) local time = os.time() - db.query("UPDATE `guild_wars` SET `status` = 4, `ended` = " .. time .. " WHERE `status` = 1 AND (`started` + 5 * 60 * 60) < " .. time) + db.query("UPDATE `guild_wars` SET `status` = 4, `ended` = " .. time .. " WHERE `status` = 1 AND `ended` != 0 AND `ended` < " .. time) return true end -guildWar:interval(100000) +guildWar:interval(60000) guildWar:register() diff --git a/data-otservbr-global/scripts/globalevents/others/online_record.lua b/data-otservbr-global/scripts/globalevents/others/online_record.lua deleted file mode 100644 index 9d7bb82e284..00000000000 --- a/data-otservbr-global/scripts/globalevents/others/online_record.lua +++ /dev/null @@ -1,7 +0,0 @@ -local playerrecord = GlobalEvent("playerrecord") -function playerrecord.onRecord(current, old) - addEvent(Game.broadcastMessage, 150, "New record: " .. current .. " players online.", MESSAGE_EVENT_ADVANCE) - return true -end - -playerrecord:register() diff --git a/data-otservbr-global/scripts/movements/others/tiles.lua b/data-otservbr-global/scripts/movements/others/tiles.lua deleted file mode 100644 index b797f0380a3..00000000000 --- a/data-otservbr-global/scripts/movements/others/tiles.lua +++ /dev/null @@ -1,87 +0,0 @@ -local increasing = { [419] = 420, [431] = 430, [452] = 453, [563] = 564, [549] = 562, [10145] = 10146 } -local decreasing = { [420] = 419, [430] = 431, [453] = 452, [564] = 563, [562] = 549, [10146] = 10145 } - --- onStepIn -local tiles = MoveEvent() - -function tiles.onStepIn(creature, item, position, fromPosition) - if not increasing[item.itemid] then - return true - end - - local player = creature:getPlayer() - if not player or player:isInGhostMode() then - return true - end - - item:transform(increasing[item.itemid]) - - if item.actionid >= 1000 then - if player:getLevel() < item.actionid - 1000 then - player:teleportTo(fromPosition, false) - position:sendMagicEffect(CONST_ME_MAGIC_BLUE) - player:sendTextMessage(MESSAGE_FAILURE, "The tile seems to be protected against unwanted intruders.") - end - return true - end - - if position:getTile():hasFlag(TILESTATE_PROTECTIONZONE) then - for _, direction in ipairs(DIRECTIONS_TABLE) do - local playerPosition = player:getPosition() - playerPosition:getNextPosition(direction) - local depotItem = playerPosition:getTile():getItemByType(ITEM_TYPE_DEPOT) - - if depotItem ~= nil then - local depotItems = 0 - for id = 1, configManager.getNumber(configKeys.DEPOT_BOXES) do - depotItems = depotItems + player:getDepotChest(id, true):getItemHoldingCount() - end - - player:sendTextMessage(MESSAGE_FAILURE, "Your depot contains " .. depotItems .. " item" .. (depotItems > 1 and "s." or ".") .. "\ - Your supply stash contains " .. player:getStashCount() .. " item" .. (player:getStashCount() > 1 and "s." or ".")) - player:setSpecialContainersAvailable(true, true, true) - return true - end - end - end - - if item.actionid ~= 0 and player:getStorageValue(item.actionid) <= 0 then - player:teleportTo(fromPosition, false) - position:sendMagicEffect(CONST_ME_MAGIC_BLUE) - player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The tile seems to be protected against unwanted intruders.") - return true - end -end - -tiles:type("stepin") - -for index, value in pairs(increasing) do - tiles:id(index) -end - -tiles:register() - -tiles = MoveEvent() - -function tiles.onStepOut(creature, item, position, fromPosition) - if not decreasing[item.itemid] then - return false - end - - local player = creature:getPlayer() - if not player or player:isInGhostMode() then - return true - end - - item:transform(decreasing[item.itemid]) - player:setSpecialContainersAvailable(false, false, false) - return true -end - -tiles:type("stepout") - -for index, value in pairs(decreasing) do - tiles:id(index) -end - -tiles:register() diff --git a/data-otservbr-global/startup/tables/chest.lua b/data-otservbr-global/startup/tables/chest.lua index f5049f93f61..228e9ba2976 100644 --- a/data-otservbr-global/startup/tables/chest.lua +++ b/data-otservbr-global/startup/tables/chest.lua @@ -1186,4 +1186,8 @@ ChestUnique = { itemId = 11810, itemPos = { x = 33195, y = 31765, z = 1 }, }, + [14042] = { + itemId = 2473, + itemPos = { x = 32099, y = 32198, z = 9 }, + }, } diff --git a/data/items/items.xml b/data/items/items.xml index faa2edfce01..097081b8dd3 100644 --- a/data/items/items.xml +++ b/data/items/items.xml @@ -1252,7 +1252,7 @@ - + @@ -1327,7 +1327,7 @@ - + @@ -1386,7 +1386,7 @@ - + @@ -1401,7 +1401,7 @@ - + @@ -1490,7 +1490,7 @@ - + @@ -1565,7 +1565,7 @@ - + @@ -1624,7 +1624,7 @@ - + @@ -1639,7 +1639,7 @@ - + @@ -2267,7 +2267,7 @@ - + @@ -2342,7 +2342,7 @@ - + @@ -2401,7 +2401,7 @@ - + @@ -2416,7 +2416,7 @@ - + @@ -2488,7 +2488,7 @@ - + @@ -2567,7 +2567,7 @@ - + @@ -2626,7 +2626,7 @@ - + @@ -2641,7 +2641,7 @@ - + @@ -3113,7 +3113,6 @@ - @@ -8267,7 +8266,7 @@ - + @@ -8281,7 +8280,7 @@ - + @@ -8317,7 +8316,7 @@ - + @@ -8398,7 +8397,7 @@ - + @@ -8439,7 +8438,7 @@ - + @@ -8461,7 +8460,7 @@ - + @@ -8500,7 +8499,7 @@ - + @@ -8608,7 +8607,7 @@ - + @@ -8701,7 +8700,7 @@ - + @@ -8772,7 +8771,7 @@ - + @@ -8794,7 +8793,7 @@ - + @@ -8817,7 +8816,7 @@ - + @@ -8964,7 +8963,7 @@ - + @@ -8978,7 +8977,7 @@ - + @@ -8999,7 +8998,7 @@ - + @@ -9074,7 +9073,7 @@ - + @@ -9218,7 +9217,7 @@ - + @@ -9260,7 +9259,7 @@ - + @@ -9282,7 +9281,7 @@ - + @@ -9339,7 +9338,7 @@ - + @@ -9417,7 +9416,7 @@ - + @@ -9461,7 +9460,7 @@ - + @@ -9521,7 +9520,7 @@ - + @@ -9568,7 +9567,7 @@ - + @@ -9580,7 +9579,7 @@ - + @@ -10827,7 +10826,7 @@ - + @@ -15647,7 +15646,7 @@ - + @@ -17989,7 +17988,7 @@ - + @@ -18117,7 +18116,7 @@ - + @@ -19369,7 +19368,7 @@ - + @@ -19392,7 +19391,7 @@ - + @@ -19428,7 +19427,7 @@ - + @@ -19508,7 +19507,7 @@ - + @@ -19594,7 +19593,7 @@ - + @@ -19616,7 +19615,7 @@ - + @@ -19674,7 +19673,7 @@ - + @@ -19696,7 +19695,7 @@ - + @@ -19739,7 +19738,7 @@ - + @@ -19762,7 +19761,7 @@ - + @@ -19784,7 +19783,7 @@ - + @@ -19887,7 +19886,7 @@ - + @@ -19910,7 +19909,7 @@ - + @@ -20085,7 +20084,7 @@ - + @@ -20106,7 +20105,7 @@ - + @@ -20120,7 +20119,7 @@ - + @@ -20141,7 +20140,7 @@ - + @@ -20156,7 +20155,7 @@ - + @@ -20172,7 +20171,7 @@ - + @@ -20322,7 +20321,7 @@ - + @@ -20364,7 +20363,7 @@ - + @@ -20421,7 +20420,7 @@ - + @@ -20435,7 +20434,7 @@ - + @@ -20477,7 +20476,7 @@ - + @@ -20499,7 +20498,7 @@ - + @@ -20514,7 +20513,7 @@ - + @@ -21456,7 +21455,7 @@ - + @@ -21479,7 +21478,7 @@ - + @@ -21503,7 +21502,7 @@ - + @@ -21526,7 +21525,7 @@ - + @@ -21548,7 +21547,7 @@ - + @@ -21572,7 +21571,7 @@ - + @@ -21596,7 +21595,7 @@ - + @@ -21611,7 +21610,7 @@ - + @@ -21634,7 +21633,7 @@ - + @@ -21649,7 +21648,7 @@ - + @@ -22373,7 +22372,7 @@ - + @@ -22429,7 +22428,7 @@ - + @@ -22484,7 +22483,7 @@ - + @@ -25285,7 +25284,7 @@ - + @@ -25373,7 +25372,7 @@ - + @@ -25396,7 +25395,7 @@ - + @@ -27223,7 +27222,7 @@ - + @@ -27238,7 +27237,7 @@ - + @@ -27274,7 +27273,7 @@ - + @@ -27296,7 +27295,7 @@ - + @@ -27376,7 +27375,7 @@ - + @@ -28881,7 +28880,7 @@ - + @@ -30741,7 +30740,7 @@ - + @@ -30884,7 +30883,7 @@ - + @@ -31910,7 +31909,7 @@ - + @@ -32300,7 +32299,7 @@ - + @@ -32657,7 +32656,7 @@ - + @@ -32674,7 +32673,7 @@ - + @@ -32936,7 +32935,7 @@ - + @@ -34608,7 +34607,7 @@ - + @@ -34632,7 +34631,7 @@ - + @@ -36066,7 +36065,7 @@ - + @@ -39422,7 +39421,7 @@ - + @@ -39487,7 +39486,7 @@ - + @@ -39625,6 +39624,12 @@ + + + + + + @@ -39953,7 +39958,7 @@ - + @@ -39975,7 +39980,7 @@ - + @@ -39998,7 +40003,7 @@ - + @@ -40073,7 +40078,7 @@ - + @@ -40095,7 +40100,7 @@ - + @@ -40118,7 +40123,7 @@ - + @@ -40193,7 +40198,7 @@ - + @@ -40215,7 +40220,7 @@ - + @@ -40238,7 +40243,7 @@ - + @@ -40255,7 +40260,7 @@ - + @@ -40279,7 +40284,7 @@ - + @@ -40304,7 +40309,7 @@ - + @@ -40321,7 +40326,7 @@ - + @@ -40345,7 +40350,7 @@ - + @@ -40370,7 +40375,7 @@ - + @@ -41953,7 +41958,7 @@ - + @@ -41989,7 +41994,7 @@ - + @@ -42021,7 +42026,7 @@ - + @@ -42039,7 +42044,7 @@ - + @@ -42057,7 +42062,7 @@ - + @@ -42211,7 +42216,7 @@ - + ogre klubb @@ -44335,7 +44340,7 @@ Awarded by TibiaMisterios.com.br"/> - + @@ -44349,7 +44354,7 @@ Awarded by TibiaMisterios.com.br"/> - + @@ -45194,7 +45199,7 @@ Awarded by TibiaMisterios.com.br"/> - + @@ -45688,7 +45693,7 @@ Awarded by TibiaMisterios.com.br"/> - + @@ -45712,7 +45717,7 @@ Awarded by TibiaMisterios.com.br"/> - + @@ -48684,8 +48689,7 @@ hands of its owner. Granted by TibiaRoyal.com"/> - + @@ -51745,7 +51749,7 @@ TibiaTome.com"/> - + @@ -51786,7 +51790,7 @@ TibiaTome.com"/> - + @@ -51827,7 +51831,7 @@ TibiaTome.com"/> - + @@ -51850,7 +51854,7 @@ TibiaTome.com"/> - + @@ -51873,7 +51877,7 @@ TibiaTome.com"/> - + @@ -54202,7 +54206,7 @@ TibiaTome.com"/> - + @@ -54307,7 +54311,7 @@ TibiaTome.com"/> - + @@ -54331,7 +54335,7 @@ TibiaTome.com"/> - + @@ -55251,7 +55255,7 @@ TibiaTome.com"/> - + @@ -55469,7 +55473,7 @@ TibiaTome.com"/> - + @@ -55513,7 +55517,7 @@ TibiaTome.com"/> - + @@ -57316,7 +57320,7 @@ TibiaTome.com"/> - + @@ -59168,7 +59172,7 @@ TibiaTome.com"/> - + @@ -59309,7 +59313,7 @@ TibiaTome.com"/> - + @@ -61756,7 +61760,7 @@ TibiaTome.com"/> - + @@ -64022,7 +64026,7 @@ TibiaTome.com"/> - + @@ -64074,7 +64078,7 @@ TibiaTome.com"/> - + @@ -64126,7 +64130,7 @@ TibiaTome.com"/> - + @@ -64154,7 +64158,7 @@ TibiaTome.com"/> - + @@ -64182,7 +64186,7 @@ TibiaTome.com"/> - + @@ -64599,7 +64603,7 @@ TibiaTome.com"/> - + @@ -65924,7 +65928,7 @@ former students at the Noodles Academy. Awarded by TibiaLabs.com"/> - + @@ -65996,7 +66000,7 @@ former students at the Noodles Academy. Awarded by TibiaLabs.com"/> - + @@ -67394,7 +67398,7 @@ former students at the Noodles Academy. Awarded by TibiaLabs.com"/> - + @@ -67419,7 +67423,7 @@ former students at the Noodles Academy. Awarded by TibiaLabs.com"/> - + @@ -67443,7 +67447,7 @@ former students at the Noodles Academy. Awarded by TibiaLabs.com"/> - + @@ -67492,7 +67496,7 @@ former students at the Noodles Academy. Awarded by TibiaLabs.com"/> - + @@ -67517,7 +67521,7 @@ former students at the Noodles Academy. Awarded by TibiaLabs.com"/> - + @@ -67563,7 +67567,7 @@ former students at the Noodles Academy. Awarded by TibiaLabs.com"/> - + @@ -67590,7 +67594,7 @@ former students at the Noodles Academy. Awarded by TibiaLabs.com"/> - + @@ -71641,7 +71645,7 @@ Granted by TibiaGoals.com"/> - + @@ -75310,7 +75314,7 @@ Granted by TibiaGoals.com"/> - + @@ -75335,7 +75339,7 @@ Granted by TibiaGoals.com"/> - + @@ -75360,7 +75364,7 @@ Granted by TibiaGoals.com"/> - + @@ -75385,7 +75389,7 @@ Granted by TibiaGoals.com"/> - + @@ -75410,7 +75414,7 @@ Granted by TibiaGoals.com"/> - + @@ -75435,7 +75439,7 @@ Granted by TibiaGoals.com"/> - + @@ -75478,7 +75482,7 @@ Granted by TibiaGoals.com"/> - + @@ -75506,7 +75510,7 @@ Granted by TibiaGoals.com"/> - + @@ -75534,7 +75538,7 @@ Granted by TibiaGoals.com"/> - + @@ -75562,7 +75566,7 @@ Granted by TibiaGoals.com"/> - + diff --git a/data/libs/functions/modal_window_helper.lua b/data/libs/functions/modal_window_helper.lua index 9de5e394cc5..ed169805b06 100644 --- a/data/libs/functions/modal_window_helper.lua +++ b/data/libs/functions/modal_window_helper.lua @@ -209,7 +209,7 @@ function ModalWindow:sendToPlayer(player) local playerId = player:getId() ModalWindows[playerId] = ModalWindows[playerId] or {} ModalWindows[playerId][self.modalWindowId] = self - player:registerEvent("modalWindowHelper") + player:registerEvent("ModalWindowHelper") self.using = self.using + 1 return modalWindow:sendToPlayer(player) end diff --git a/data/libs/functions/player.lua b/data/libs/functions/player.lua index 2662db60d11..03e88d7ccca 100644 --- a/data/libs/functions/player.lua +++ b/data/libs/functions/player.lua @@ -966,3 +966,37 @@ do return true end end + +function Player:questKV(questName) + return self:kv():scoped("quests"):scoped(questName) +end + +function Player:canGetReward(rewardId, questName) + if self:questKV(questName):get("completed") then + self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The box is empty.") + return false + end + + local rewardItem = ItemType(rewardId) + if not rewardItem then + self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Reward item is wrong, please contact an administrator.") + return false + end + + local itemWeight = rewardItem:getWeight() / 100 + local baseMessage = "You have found a " .. rewardItem:getName() + local backpack = self:getSlotItem(CONST_SLOT_BACKPACK) + if not backpack or backpack:getEmptySlots(true) < 1 then + baseMessage = baseMessage .. ", but you have no room to take it." + self:sendTextMessage(MESSAGE_EVENT_ADVANCE, baseMessage) + return false + end + + if (self:getFreeCapacity() / 100) < itemWeight then + baseMessage = baseMessage .. ". Weighing " .. itemWeight .. " oz, it is too heavy for you to carry." + self:sendTextMessage(MESSAGE_EVENT_ADVANCE, baseMessage) + return false + end + + return true +end diff --git a/data/libs/functions/revscriptsys.lua b/data/libs/functions/revscriptsys.lua index 5a31ec086f3..84b8275e3ce 100644 --- a/data/libs/functions/revscriptsys.lua +++ b/data/libs/functions/revscriptsys.lua @@ -108,7 +108,7 @@ do local function EventCallbackNewIndex(self, key, value) local func = eventCallbacks[key] if func and type(func) == "function" then - logger.debug("[Registering EventCallback: {}", key) + logger.trace("[Registering EventCallback: {}", key) func(self, value) self:type(key) else diff --git a/data-otservbr-global/scripts/actions/other/anniversary_reward_boxes.lua b/data/scripts/actions/items/anniversary_reward_boxes.lua similarity index 92% rename from data-otservbr-global/scripts/actions/other/anniversary_reward_boxes.lua rename to data/scripts/actions/items/anniversary_reward_boxes.lua index 8327222a570..d5d36bb7455 100644 --- a/data-otservbr-global/scripts/actions/other/anniversary_reward_boxes.lua +++ b/data/scripts/actions/items/anniversary_reward_boxes.lua @@ -55,22 +55,24 @@ local config = { } local rewardBox = Action() + function rewardBox.onUse(player, item, fromPosition, itemEx, toPosition) local box = config[item:getId()] - if not box or not player then + if not box then return false end - for i = 1, #box do - if box[i] then - player:addItem(box[i].id, box[i].count) - player:getPosition():sendMagicEffect(CONST_ME_PRISMATIC_SPARK) - end + + for _, reward in ipairs(box) do + player:addItem(reward.id, reward.count) + player:getPosition():sendMagicEffect(CONST_ME_PRISMATIC_SPARK) end + item:remove() return true end -for index, value in pairs(config) do +for index, _ in pairs(config) do rewardBox:id(index) end + rewardBox:register() diff --git a/data/scripts/actions/items/die.lua b/data/scripts/actions/items/die.lua new file mode 100644 index 00000000000..661926e79ea --- /dev/null +++ b/data/scripts/actions/items/die.lua @@ -0,0 +1,36 @@ +local die = Action() + +function die.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local position = item:getPosition() + local value = math.random(1, 6) + local isInGhostMode = player:isInGhostMode() + + if not isInGhostMode then + position:sendMagicEffect(CONST_ME_CRAPS) + + local spectators = Game.getSpectators(position, false, true, 3, 3) + for _, spectator in ipairs(spectators) do + player:say(player:getName() .. " rolled a " .. value .. ".", TALKTYPE_MONSTER_SAY, isInGhostMode, spectator, position) + end + end + + if value == 6 then + local rolledSixCount = player:kv():get("die-rolled-six") or 0 + player:kv():set("die-rolled-six", rolledSixCount + 1) + + if rolledSixCount == 2 then + player:addAchievement("Number of the Beast") + end + else + player:kv():remove("die-rolled-six") + end + + item:transform(5791 + value) + return true +end + +for items = 5792, 5797 do + die:id(items) +end + +die:register() diff --git a/data-canary/scripts/actions/other/explosive_present.lua b/data/scripts/actions/items/explosive_present.lua similarity index 81% rename from data-canary/scripts/actions/other/explosive_present.lua rename to data/scripts/actions/items/explosive_present.lua index 33878ffda93..2ca4730decd 100644 --- a/data-canary/scripts/actions/other/explosive_present.lua +++ b/data/scripts/actions/items/explosive_present.lua @@ -3,9 +3,10 @@ local explosivePresent = Action() function explosivePresent.onUse(player, item, fromPosition, target, toPosition, isHotkey) player:say("KABOOOOOOOOOOM!", TALKTYPE_MONSTER_SAY) player:getPosition():sendMagicEffect(CONST_ME_FIREAREA) + player:addAchievement("Joke's on You") item:remove() return true end -explosivePresent:id(3218) +explosivePresent:id(906) explosivePresent:register() diff --git a/data-otservbr-global/scripts/actions/other/food.lua b/data/scripts/actions/items/foods.lua similarity index 94% rename from data-otservbr-global/scripts/actions/other/food.lua rename to data/scripts/actions/items/foods.lua index 3c6b5290fed..4a8072d163e 100644 --- a/data-otservbr-global/scripts/actions/other/food.lua +++ b/data/scripts/actions/items/foods.lua @@ -82,7 +82,6 @@ local foods = { [8017] = { 5, "Munch." }, -- beetroot [8019] = { 11, "Yum." }, -- chocolate cake [8177] = { 7, "Slurp." }, -- yummy gummy worm - [8194] = { 0, "Urgh.", CONST_ME_MAGIC_BLUE }, -- garlic bread [8197] = { 5, "Crunch." }, -- bulb of garlic [9537] = { 0, "Your head begins to feel better." }, -- headache pill [10329] = { 15, "Yum." }, -- rice ball @@ -124,29 +123,24 @@ local foods = { } local food = Action() + function food.onUse(player, item, fromPosition, target, toPosition, isHotkey) - local bloodBrothersStorage = Storage.Quest.U8_4.BloodBrothers local itemFood = foods[item.itemid] - local effect = itemFood[3] if not itemFood then return false end + local condition = player:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT) if condition and math.floor(condition:getTicks() / 1000 + (itemFood[1] * 12)) >= 1200 then player:sendTextMessage(MESSAGE_FAILURE, "You are full.") return true end - if item.itemid == 8194 and player:getStorageValue(bloodBrothersStorage.GarlicBread) == 0 then - player:setStorageValue(bloodBrothersStorage.GarlicBread, 1) - end + player:feed(itemFood[1] * 12) player:say(itemFood[2], TALKTYPE_MONSTER_SAY) - item:remove(1) player:updateSupplyTracker(item) player:getPosition():sendSingleSoundEffect(SOUND_EFFECT_TYPE_ACTION_EAT, player:isInGhostMode() and nil or player) - if effect then - player:getPosition():sendMagicEffect(effect) - end + item:remove(1) return true end diff --git a/data/scripts/actions/items/garlic_bread.lua b/data/scripts/actions/items/garlic_bread.lua new file mode 100644 index 00000000000..315dbbadd5c --- /dev/null +++ b/data/scripts/actions/items/garlic_bread.lua @@ -0,0 +1,9 @@ +local garlicBread = Action() + +function garlicBread.onUse(player, item, fromPosition, target, toPosition, isHotkey) + player:say("After taking a small bite you decide that you don't want to eat that.", TALKTYPE_MONSTER_SAY) + return true +end + +garlicBread:id(8194) +garlicBread:register() diff --git a/data/scripts/actions/items/scroll_of_ascension.lua b/data/scripts/actions/items/scroll_of_ascension.lua index b763460c09b..1b32d0d994a 100644 --- a/data/scripts/actions/items/scroll_of_ascension.lua +++ b/data/scripts/actions/items/scroll_of_ascension.lua @@ -11,15 +11,10 @@ function scrollOfAscension.onUse(player, item, fromPosition, target, toPosition, return true end - if math.random(10) > 1 then - player:setMonsterOutfit("Demon", 30 * 10 * 1000) - else - player:setMonsterOutfit("Ferumbras", 30 * 10 * 1000) - end - - player:setExhaustion("scroll-of-ascension", 60 * 60) + player:setMonsterOutfit(math.random(10) > 1 and "Demon" or "Ferumbras", 5 * 60 * 1000) player:say("Magical sparks whirl around the scroll as you read it and then your appearance is changing.", TALKTYPE_MONSTER_SAY) - player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) + player:getPosition():sendMagicEffect(CONST_ME_HITBYFIRE) + player:setExhaustion("scroll-of-ascension", 60 * 60) return true end diff --git a/data-canary/scripts/actions/other/voodoo_doll.lua b/data/scripts/actions/items/voodoo_doll.lua similarity index 92% rename from data-canary/scripts/actions/other/voodoo_doll.lua rename to data/scripts/actions/items/voodoo_doll.lua index 07940e32864..6e906e9b996 100644 --- a/data-canary/scripts/actions/other/voodoo_doll.lua +++ b/data/scripts/actions/items/voodoo_doll.lua @@ -8,6 +8,7 @@ function voodooDoll.onUse(player, item, fromPosition, target, toPosition, isHotk local text = "" if math.random(100) <= 5 then text = "You concentrate on your victim and hit the needle in the doll." + player:addAchievement("Dark Voodoo Priest") toPosition:sendMagicEffect(CONST_ME_DRAWBLOOD, player) else text = "You concentrate on your victim, hit the needle in the doll.......but nothing happens." diff --git a/data-otservbr-global/scripts/actions/other/carpets.lua b/data/scripts/actions/objects/carpets.lua similarity index 93% rename from data-otservbr-global/scripts/actions/other/carpets.lua rename to data/scripts/actions/objects/carpets.lua index ccd69a7e446..6232eb2f1a1 100644 --- a/data-otservbr-global/scripts/actions/other/carpets.lua +++ b/data/scripts/actions/objects/carpets.lua @@ -170,23 +170,35 @@ function carpets.onUse(player, item, fp, target, toPosition, isHotkey) end local fromPosition = item:getPosition() - local tile = Tile(fromPosition) - if not fromPosition:getTile():getHouse() then + local tile = fromPosition:getTile() + if not tile then player:sendTextMessage(MESSAGE_FAILURE, "You may use this only inside a house.") - elseif tile:getItemCountById(item.itemid) == 1 then + return true + end + + local house = tile:getHouse() + if not house then + player:sendTextMessage(MESSAGE_FAILURE, "You may use this only inside a house.") + return true + end + + local itemCount = tile:getItemCountById(item.itemid) + if itemCount == 1 then local topItem = tile:getTopTopItem() if topItem and topItem:canReceiveAutoCarpet() then item:remove() return true end + for k, v in pairs(carpetItems) do - if tile:getItemCountById(k) > 0 and k ~= item.itemid then + if k ~= item.itemid and tile:getItemCountById(k) > 0 then player:sendCancelMessage(Game.getReturnMessage(RETURNVALUE_NOTPOSSIBLE)) return true end end - item:transform(carpet) end + + item:transform(carpet) return true end diff --git a/data-otservbr-global/scripts/creaturescripts/monster/white_deer.lua b/data/scripts/creaturescripts/monster/white_deer_death.lua similarity index 90% rename from data-otservbr-global/scripts/creaturescripts/monster/white_deer.lua rename to data/scripts/creaturescripts/monster/white_deer_death.lua index 5fff12eaad4..cc9c9377a6e 100644 --- a/data-otservbr-global/scripts/creaturescripts/monster/white_deer.lua +++ b/data/scripts/creaturescripts/monster/white_deer_death.lua @@ -1,11 +1,11 @@ local config = { - -- ordered by chance, the last chance being 100 { chance = 30, monster = "Enraged White Deer", message = "The white deer summons all his strength and turns to fight!" }, { chance = 100, monster = "Desperate White Deer", message = "The white deer desperately tries to escape!" }, } local whiteDeerDeath = CreatureEvent("WhiteDeerDeath") -function whiteDeerDeath.onDeath(creature, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified) + +function whiteDeerDeath.onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified, mostDamageUnjustified) local targetMonster = creature:getMonster() if not targetMonster or targetMonster:getMaster() then return true diff --git a/data-otservbr-global/scripts/creaturescripts/monster/white_deer_scout.lua b/data/scripts/creaturescripts/monster/white_deer_scouts.lua similarity index 81% rename from data-otservbr-global/scripts/creaturescripts/monster/white_deer_scout.lua rename to data/scripts/creaturescripts/monster/white_deer_scouts.lua index 8466df46af7..214c0ad5269 100644 --- a/data-otservbr-global/scripts/creaturescripts/monster/white_deer_scout.lua +++ b/data/scripts/creaturescripts/monster/white_deer_scouts.lua @@ -1,5 +1,6 @@ local whiteDeerScoutsDeath = CreatureEvent("WhiteDeerScoutsDeath") -function whiteDeerScoutsDeath.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified) + +function whiteDeerScoutsDeath.onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified, mostDamageUnjustified) local targetMonster = creature:getMonster() if not targetMonster or targetMonster:getMaster() then return true @@ -16,6 +17,7 @@ function whiteDeerScoutsDeath.onDeath(creature, corpse, lasthitkiller, mostdamag targetMonster:say("The elves came too late to save the deer, however they might avenge it.", TALKTYPE_MONSTER_SAY) end + return true end whiteDeerScoutsDeath:register() diff --git a/data-canary/scripts/creaturescripts/modal_window_helper.lua b/data/scripts/creaturescripts/others/modal_window_helper.lua similarity index 93% rename from data-canary/scripts/creaturescripts/modal_window_helper.lua rename to data/scripts/creaturescripts/others/modal_window_helper.lua index d2651af1e69..a3a33b3d274 100644 --- a/data-canary/scripts/creaturescripts/modal_window_helper.lua +++ b/data/scripts/creaturescripts/others/modal_window_helper.lua @@ -1,4 +1,4 @@ -local creatureEvent = CreatureEvent("modalWindowHelper") +local creatureEvent = CreatureEvent("ModalWindowHelper") function creatureEvent.onModalWindow(player, modalWindowId, buttonId, choiceId) local playerId = player:getId() diff --git a/data-otservbr-global/scripts/creaturescripts/others/logout.lua b/data/scripts/creaturescripts/player/logout.lua similarity index 73% rename from data-otservbr-global/scripts/creaturescripts/others/logout.lua rename to data/scripts/creaturescripts/player/logout.lua index 07e0d5dfce5..cab57c5ad68 100644 --- a/data-otservbr-global/scripts/creaturescripts/others/logout.lua +++ b/data/scripts/creaturescripts/player/logout.lua @@ -1,22 +1,21 @@ local playerLogout = CreatureEvent("PlayerLogout") + function playerLogout.onLogout(player) local playerId = player:getId() - if _G.NextUseStaminaTime[playerId] ~= nil then + if _G.NextUseStaminaTime[playerId] then _G.NextUseStaminaTime[playerId] = nil end - player:setStorageValue(Storage.ExerciseDummyExhaust, 0) - local stats = player:inBossFight() if stats then local boss = Monster(stats.bossId) - -- Player logged out (or died) in the middle of a boss fight, store his damageOut and stamina if boss then local dmgOut = boss:getDamageMap()[playerId] if dmgOut then stats.damageOut = (stats.damageOut or 0) + dmgOut.total end + stats.stamina = player:getStamina() end end @@ -26,8 +25,6 @@ function playerLogout.onLogout(player) _G.OnExerciseTraining[playerId] = nil player:setTraining(false) end - - player:setStorageValue(17101, 0) return true end diff --git a/data/scripts/creaturescripts/player/name_lock.lua b/data/scripts/creaturescripts/player/name_lock.lua index 322e8d135b8..cb2af81de3f 100644 --- a/data/scripts/creaturescripts/player/name_lock.lua +++ b/data/scripts/creaturescripts/player/name_lock.lua @@ -6,7 +6,7 @@ function CheckNamelock(player) player:setMoveLocked(true) player:teleportTo(player:getTown():getTemplePosition()) - player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Your name has been locked for the following reason: " .. namelockReason .. ".") + player:sendTextMessage(MESSAGE_ADMINISTRATOR, "Your name has been locked for the following reason: " .. namelockReason .. ".") player:openStore("extras") addPlayerEvent(sendRequestPurchaseData, 50, player, 65002, GameStore.ClientOfferTypes.CLIENT_STORE_OFFER_NAMECHANGE) addPlayerEvent(CheckNamelock, 30000, player) diff --git a/data/scripts/creaturescripts/others/offline_training.lua b/data/scripts/creaturescripts/player/offline_training.lua similarity index 100% rename from data/scripts/creaturescripts/others/offline_training.lua rename to data/scripts/creaturescripts/player/offline_training.lua diff --git a/data-otservbr-global/scripts/creaturescripts/others/regenerate_stamina.lua b/data/scripts/creaturescripts/player/regenerate_stamina.lua similarity index 99% rename from data-otservbr-global/scripts/creaturescripts/others/regenerate_stamina.lua rename to data/scripts/creaturescripts/player/regenerate_stamina.lua index 4c70f7eb080..52c78e93f39 100644 --- a/data-otservbr-global/scripts/creaturescripts/others/regenerate_stamina.lua +++ b/data/scripts/creaturescripts/player/regenerate_stamina.lua @@ -1,4 +1,5 @@ local regenerateStamina = CreatureEvent("RegenerateStamina") + function regenerateStamina.onLogin(player) if not configManager.getBoolean(configKeys.STAMINA_SYSTEM) then return true @@ -6,6 +7,7 @@ function regenerateStamina.onLogin(player) local lastLogout = player:getLastLogout() local offlineTime = lastLogout ~= 0 and math.min(os.time() - lastLogout, 86400 * 21) or 0 + offlineTime = offlineTime - 600 if offlineTime < 180 then @@ -15,12 +17,14 @@ function regenerateStamina.onLogin(player) local staminaMinutes = player:getStamina() local maxNormalStaminaRegen = 2340 - math.min(2340, staminaMinutes) local regainStaminaMinutes = offlineTime / 180 + if regainStaminaMinutes > maxNormalStaminaRegen then local happyHourStaminaRegen = (offlineTime - (maxNormalStaminaRegen * 180)) / 360 staminaMinutes = math.min(2520, math.max(2340, staminaMinutes) + happyHourStaminaRegen) else staminaMinutes = staminaMinutes + regainStaminaMinutes end + player:setStamina(staminaMinutes) return true end diff --git a/data/scripts/creaturescripts/player/update_player_on_advanced_level.lua b/data/scripts/creaturescripts/player/update_player_on_advanced_level.lua new file mode 100644 index 00000000000..aa22976740c --- /dev/null +++ b/data/scripts/creaturescripts/player/update_player_on_advanced_level.lua @@ -0,0 +1,15 @@ +local updatePlayerOnAdvancedLevel = CreatureEvent("UpdatePlayerOnAdvancedLevel") + +function updatePlayerOnAdvancedLevel.onAdvance(player, skill, oldLevel, newLevel) + if skill ~= SKILL_LEVEL or newLevel <= oldLevel then + return true + end + + player:addHealth(player:getMaxHealth()) + player:addMana(player:getMaxMana()) + player:getFinalLowLevelBonus() + player:save() + return true +end + +updatePlayerOnAdvancedLevel:register() diff --git a/data-canary/scripts/globalevents/record.lua b/data/scripts/globalevents/online_record.lua similarity index 52% rename from data-canary/scripts/globalevents/record.lua rename to data/scripts/globalevents/online_record.lua index 981b2db003c..506fd328ac1 100644 --- a/data-canary/scripts/globalevents/record.lua +++ b/data/scripts/globalevents/online_record.lua @@ -1,8 +1,8 @@ -local globalevent = GlobalEvent("Player Record") +local onlineRecord = GlobalEvent("OnlineRecord") -function globalevent.onRecord(current, old) +function onlineRecord.onRecord(current, old) addEvent(Game.broadcastMessage, 150, "New record: " .. current .. " players are logged in.", MESSAGE_LOGIN) return true end -globalevent:register() +onlineRecord:register() diff --git a/data/scripts/lib/register_achievements.lua b/data/scripts/lib/register_achievements.lua index b906afd287a..11d238d8bcf 100644 --- a/data/scripts/lib/register_achievements.lua +++ b/data/scripts/lib/register_achievements.lua @@ -551,7 +551,7 @@ Functions: ACHIEVEMENT_FIRST = 1 ACHIEVEMENT_LAST = #ACHIEVEMENTS -for id, achievTable in ipairs(ACHIEVEMENTS) do +for id, achievTable in pairs(ACHIEVEMENTS) do if achievTable.name == nil then logger.error(string.format("[Achievements registration] - Invalid achievement with no name, id: '%s'", id)) goto continue -- Skips to the next iteration using the 'continue' label @@ -567,7 +567,7 @@ for id, achievTable in ipairs(ACHIEVEMENTS) do local grade = achievTable.grade or 0 local points = achievTable.points or 0 - logger.debug("[Achievements registration] - Registering achievement '{}' with id '{}'", achievTable.name, id) + logger.trace("[Achievements registration] - Registering achievement '{}' with id '{}'", achievTable.name, id) Game.registerAchievement(id, achievTable.name, achievTable.description, secret, grade, points) ::continue:: -- Label used by 'goto' to continue the loop diff --git a/data-canary/scripts/movements/tiles.lua b/data/scripts/movements/special_tiles.lua similarity index 86% rename from data-canary/scripts/movements/tiles.lua rename to data/scripts/movements/special_tiles.lua index 5f0f74e2c80..a1ec92dbbad 100644 --- a/data-canary/scripts/movements/tiles.lua +++ b/data/scripts/movements/special_tiles.lua @@ -1,17 +1,15 @@ local increasing = { [419] = 420, [431] = 430, [452] = 453, [563] = 564, [549] = 562, [10145] = 10146 } local decreasing = { [420] = 419, [430] = 431, [453] = 452, [564] = 563, [562] = 549, [10146] = 10145 } --- onStepIn local tile = MoveEvent() -tile:type("stepin") function tile.onStepIn(creature, item, position, fromPosition) - if not increasing[item.itemid] then + local player = creature:getPlayer() + if not player or player:isInGhostMode() then return true end - local player = creature:getPlayer() - if not player or player:isInGhostMode() then + if not increasing[item.itemid] then return true end @@ -30,14 +28,19 @@ function tile.onStepIn(creature, item, position, fromPosition) for _, direction in ipairs(DIRECTIONS_TABLE) do local playerPosition = player:getPosition() playerPosition:getNextPosition(direction) + local depotItem = playerPosition:getTile():getItemByType(ITEM_TYPE_DEPOT) - if depotItem ~= nil then + if depotItem then local depotItems = 0 + for id = 1, configManager.getNumber(configKeys.DEPOT_BOXES) do depotItems = depotItems + player:getDepotChest(id, true):getItemHoldingCount() end - player:sendTextMessage(MESSAGE_FAILURE, "Your depot contains " .. depotItems .. " item" .. (depotItems > 1 and "s." or ".") .. "\ - Your supply stash contains " .. player:getStashCount() .. " item" .. (player:getStashCount() > 1 and "s." or ".")) + + local depotMessage = "Your depot contains " .. depotItems .. " item" .. (depotItems ~= 1 and "s." or ".") + local stashMessage = "Your supply stash contains " .. player:getStashCount() .. " item" .. (player:getStashCount() ~= 1 and "s." or ".") + + player:sendTextMessage(MESSAGE_FAILURE, depotMessage .. "\n" .. stashMessage) player:setSpecialContainersAvailable(true, true, true) return true end @@ -57,18 +60,18 @@ for index, value in pairs(increasing) do tile:id(index) end +tile:type("stepin") tile:register() tile = MoveEvent() -tile:type("stepout") function tile.onStepOut(creature, item, position, fromPosition) - if not decreasing[item.itemid] then + local player = creature:getPlayer() + if not player or player:isInGhostMode() then return true end - local player = creature:getPlayer() - if not player or player:isInGhostMode() then + if not decreasing[item.itemid] then return true end @@ -81,4 +84,5 @@ for index, value in pairs(decreasing) do tile:id(index) end +tile:type("stepout") tile:register() diff --git a/data-canary/scripts/movements/yellow_pillow.lua b/data/scripts/movements/yellow_pillow.lua similarity index 66% rename from data-canary/scripts/movements/yellow_pillow.lua rename to data/scripts/movements/yellow_pillow.lua index 6d981448ca5..f0a433f2fb7 100644 --- a/data-canary/scripts/movements/yellow_pillow.lua +++ b/data/scripts/movements/yellow_pillow.lua @@ -1,14 +1,16 @@ local yellowPillow = MoveEvent() -yellowPillow:type("stepin") -function yellowPillow.onStepIn(player, item, position, fromPosition) +function yellowPillow.onStepIn(creature, item, position, fromPosition) + local player = creature:getPlayer() if not player or player:isInGhostMode() then return true end + player:say("Faaart!", TALKTYPE_MONSTER_SAY) item:getPosition():sendMagicEffect(CONST_ME_POFF) return true end -yellowPillow:id(8072) +yellowPillow:id(2397) +yellowPillow:type("stepin") yellowPillow:register() diff --git a/data/scripts/talkactions/gm/ban.lua b/data/scripts/talkactions/gm/ban.lua index 8b46394a3e2..0ab07040333 100644 --- a/data/scripts/talkactions/gm/ban.lua +++ b/data/scripts/talkactions/gm/ban.lua @@ -37,11 +37,11 @@ function ban.onSay(player, words, param) local target = Player(name) if target then local text = target:getName() .. " has been banned" - player:sendTextMessage(MESSAGE_ADMINISTRADOR, text) + player:sendTextMessage(MESSAGE_ADMINISTRATOR, text) Webhook.sendMessage("Player Banned", text .. " reason: " .. reason .. ". (by: " .. player:getName() .. ")", WEBHOOK_COLOR_YELLOW, announcementChannels["serverAnnouncements"]) target:remove() else - player:sendTextMessage(MESSAGE_ADMINISTRADOR, name .. " has been banned.") + player:sendTextMessage(MESSAGE_ADMINISTRATOR, name .. " has been banned.") end end diff --git a/data/scripts/talkactions/gm/broadcast.lua b/data/scripts/talkactions/gm/broadcast.lua index 021f218ebe3..dffbe1bb0e9 100644 --- a/data/scripts/talkactions/gm/broadcast.lua +++ b/data/scripts/talkactions/gm/broadcast.lua @@ -5,7 +5,7 @@ function Broadcast(text, filter) if filter and not filter(targetPlayer) then goto continue end - targetPlayer:sendTextMessage(MESSAGE_ADMINISTRADOR, text) + targetPlayer:sendTextMessage(MESSAGE_ADMINISTRATOR, text) ::continue:: end end diff --git a/data/scripts/talkactions/gm/clean.lua b/data/scripts/talkactions/gm/clean.lua index 6fe5f3cddfa..18ab149e216 100644 --- a/data/scripts/talkactions/gm/clean.lua +++ b/data/scripts/talkactions/gm/clean.lua @@ -6,7 +6,7 @@ function clean.onSay(player, words, param) local itemCount = cleanMap() if itemCount ~= 0 then - player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Cleaned " .. itemCount .. " item" .. (itemCount > 1 and "s" or "") .. " from the map.") + player:sendTextMessage(MESSAGE_ADMINISTRATOR, "Cleaned " .. itemCount .. " item" .. (itemCount > 1 and "s" or "") .. " from the map.") end return true end diff --git a/data/scripts/talkactions/gm/mc_check.lua b/data/scripts/talkactions/gm/mc_check.lua index c93661053e4..1815b7fdc9d 100644 --- a/data/scripts/talkactions/gm/mc_check.lua +++ b/data/scripts/talkactions/gm/mc_check.lua @@ -4,7 +4,7 @@ function mcCheck.onSay(player, words, param) -- create log logCommand(player, words, param) - player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Multiclient Check List:") + player:sendTextMessage(MESSAGE_ADMINISTRATOR, "Multiclient Check List:") local ipList = {} local players = Game.getPlayers() for i = 1, #players do @@ -29,7 +29,7 @@ function mcCheck.onSay(player, words, param) tmpPlayer = list[i] message = ("%s, %s [%d]"):format(message, tmpPlayer:getName(), tmpPlayer:getLevel()) end - player:sendTextMessage(MESSAGE_ADMINISTRADOR, message .. ".") + player:sendTextMessage(MESSAGE_ADMINISTRATOR, message .. ".") end end return true diff --git a/data/scripts/talkactions/gm/namelock.lua b/data/scripts/talkactions/gm/namelock.lua index 1b204759e02..27e41710096 100644 --- a/data/scripts/talkactions/gm/namelock.lua +++ b/data/scripts/talkactions/gm/namelock.lua @@ -33,7 +33,7 @@ function namelock.onSay(player, words, param) target:kv():set("namelock", reason) local text = target:getName() .. " has been namelocked" logger.info(text .. ", reason: " .. reason) - player:sendTextMessage(MESSAGE_ADMINISTRADOR, text) + player:sendTextMessage(MESSAGE_ADMINISTRATOR, text) Webhook.sendMessage("Player Namelocked", text .. " reason: " .. reason .. ".", WEBHOOK_COLOR_YELLOW, announcementChannels["serverAnnouncements"]) if online then CheckNamelock(target) diff --git a/data/scripts/talkactions/gm/unban.lua b/data/scripts/talkactions/gm/unban.lua index 264335eeec7..3d1caba8b77 100644 --- a/data/scripts/talkactions/gm/unban.lua +++ b/data/scripts/talkactions/gm/unban.lua @@ -18,7 +18,7 @@ function unban.onSay(player, words, param) db.asyncQuery("DELETE FROM `ip_bans` WHERE `ip` = " .. Result.getNumber(resultId, "lastip")) Result.free(resultId) local text = param .. " has been unbanned." - player:sendTextMessage(MESSAGE_ADMINISTRADOR, text) + player:sendTextMessage(MESSAGE_ADMINISTRATOR, text) Webhook.sendMessage("Player Unbanned", text .. " (by: " .. player:getName() .. ")", WEBHOOK_COLOR_YELLOW, announcementChannels["serverAnnouncements"]) return true end diff --git a/data/scripts/talkactions/god/add_bosstiary_kills.lua b/data/scripts/talkactions/god/add_bosstiary_kills.lua index 4e5aecdfbd4..a6463c26162 100644 --- a/data/scripts/talkactions/god/add_bosstiary_kills.lua +++ b/data/scripts/talkactions/god/add_bosstiary_kills.lua @@ -24,9 +24,9 @@ function talkaction.onSay(player, words, param) local message = "Added received kills: " .. kills .. ", for boss: " .. monsterName if target == player then - player:sendTextMessage(MESSAGE_ADMINISTRADOR, message .. " to yourself.") + player:sendTextMessage(MESSAGE_ADMINISTRATOR, message .. " to yourself.") else - player:sendTextMessage(MESSAGE_ADMINISTRADOR, message .. " to player: " .. targetName) + player:sendTextMessage(MESSAGE_ADMINISTRATOR, message .. " to player: " .. targetName) target:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You received kills: " .. kills .. ", to boss: " .. monsterName) end target:addBosstiaryKill(monsterName, kills) diff --git a/data/scripts/talkactions/god/add_mount.lua b/data/scripts/talkactions/god/add_mount.lua index 813f46f38a9..b8b2f00dda1 100644 --- a/data/scripts/talkactions/god/add_mount.lua +++ b/data/scripts/talkactions/god/add_mount.lua @@ -22,8 +22,8 @@ function addOutfit.onSay(player, words, param) if target then local mount = tonumber(split[2]) target:addMount(mount) - target:sendTextMessage(MESSAGE_ADMINISTRADOR, "" .. player:getName() .. " has been added a new mount for you.") - player:sendTextMessage(MESSAGE_ADMINISTRADOR, "You have sucessfull added mount " .. mount .. " to the player " .. target:getName() .. ".") + target:sendTextMessage(MESSAGE_ADMINISTRATOR, "" .. player:getName() .. " has been added a new mount for you.") + player:sendTextMessage(MESSAGE_ADMINISTRATOR, "You have sucessfull added mount " .. mount .. " to the player " .. target:getName() .. ".") if printConsole then logger.info("[addOutfit.onSay] - Player: {} has been added mount: {} to the player: {}", player:getName(), lookType, target:getName()) end diff --git a/data/scripts/talkactions/god/add_outfit.lua b/data/scripts/talkactions/god/add_outfit.lua index 825aaf84c7e..a27fb4f8a18 100644 --- a/data/scripts/talkactions/god/add_outfit.lua +++ b/data/scripts/talkactions/god/add_outfit.lua @@ -24,8 +24,8 @@ function addOutfit.onSay(player, words, param) if target then local lookType = tonumber(split[2]) target:addOutfit(lookType) - target:sendTextMessage(MESSAGE_ADMINISTRADOR, "" .. player:getName() .. " has been added a new outfit for you.") - player:sendTextMessage(MESSAGE_ADMINISTRADOR, "You have sucessfull added looktype " .. lookType .. " to the player " .. target:getName() .. ".") + target:sendTextMessage(MESSAGE_ADMINISTRATOR, "" .. player:getName() .. " has been added a new outfit for you.") + player:sendTextMessage(MESSAGE_ADMINISTRATOR, "You have sucessfull added looktype " .. lookType .. " to the player " .. target:getName() .. ".") if printConsole then logger.info("[addOutfit.onSay] - Player: {} has been added looktype: {} to the player: {}", player:getName(), lookType, target:getName()) end diff --git a/data/scripts/talkactions/god/close_server.lua b/data/scripts/talkactions/god/close_server.lua index 930cde5be79..ad8cfadef2c 100644 --- a/data/scripts/talkactions/god/close_server.lua +++ b/data/scripts/talkactions/god/close_server.lua @@ -19,10 +19,10 @@ function closeServer.onSay(player, words, param) end elseif param == "maintainance" then Game.setGameState(GAME_STATE_MAINTAIN) - player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Server is set to maintenance mode.") + player:sendTextMessage(MESSAGE_ADMINISTRATOR, "Server is set to maintenance mode.") else Game.setGameState(GAME_STATE_CLOSED) - player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Server is now closed.") + player:sendTextMessage(MESSAGE_ADMINISTRATOR, "Server is now closed.") Webhook.sendMessage(":yellow_square: Server was closed by: **" .. player:getName() .. "**", announcementChannels["serverAnnouncements"]) end return true diff --git a/data/scripts/talkactions/god/ip_ban.lua b/data/scripts/talkactions/god/ip_ban.lua index 9826d726c87..09269de446f 100644 --- a/data/scripts/talkactions/god/ip_ban.lua +++ b/data/scripts/talkactions/god/ip_ban.lua @@ -32,14 +32,14 @@ function ipBan.onSay(player, words, param) resultId = db.storeQuery("SELECT 1 FROM `ip_bans` WHERE `ip` = " .. targetIp) if resultId ~= false then - player:sendTextMessage(MESSAGE_ADMINISTRADOR, targetName .. " is already IP banned.") + player:sendTextMessage(MESSAGE_ADMINISTRATOR, targetName .. " is already IP banned.") Result.free(resultId) return true end local timeNow = os.time() db.query("INSERT INTO `ip_bans` (`ip`, `reason`, `banned_at`, `expires_at`, `banned_by`) VALUES (" .. targetIp .. ", '', " .. timeNow .. ", " .. timeNow + (ipBanDays * 86400) .. ", " .. player:getGuid() .. ")") - player:sendTextMessage(MESSAGE_ADMINISTRADOR, targetName .. " has been IP banned.") + player:sendTextMessage(MESSAGE_ADMINISTRATOR, targetName .. " has been IP banned.") return true end diff --git a/data/scripts/talkactions/god/open_server.lua b/data/scripts/talkactions/god/open_server.lua index 84f0b4afe49..83ac47878a1 100644 --- a/data/scripts/talkactions/god/open_server.lua +++ b/data/scripts/talkactions/god/open_server.lua @@ -5,7 +5,7 @@ function openServer.onSay(player, words, param) logCommand(player, words, param) Game.setGameState(GAME_STATE_NORMAL) - player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Server is now open.") + player:sendTextMessage(MESSAGE_ADMINISTRATOR, "Server is now open.") Webhook.sendMessage(":green_circle: Server was opened by: **" .. player:getName() .. "**", announcementChannels["serverAnnouncements"]) return true end diff --git a/data/scripts/talkactions/god/raids.lua b/data/scripts/talkactions/god/raids.lua index 15f21801293..b9b4b909668 100644 --- a/data/scripts/talkactions/god/raids.lua +++ b/data/scripts/talkactions/god/raids.lua @@ -12,18 +12,18 @@ function startRaid.onSay(player, words, param) if Raid.registry[param] then local raid = Raid.registry[param] if raid:tryStart(true) then - player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Raid " .. param .. " started.") + player:sendTextMessage(MESSAGE_ADMINISTRATOR, "Raid " .. param .. " started.") else - player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Raid " .. param .. " could not be started.") + player:sendTextMessage(MESSAGE_ADMINISTRATOR, "Raid " .. param .. " could not be started.") end return true end local returnValue = Game.startRaid(param) if returnValue ~= RETURNVALUE_NOERROR then - player:sendTextMessage(MESSAGE_ADMINISTRADOR, Game.getReturnMessage(returnValue)) + player:sendTextMessage(MESSAGE_ADMINISTRATOR, Game.getReturnMessage(returnValue)) else - player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Raid started.") + player:sendTextMessage(MESSAGE_ADMINISTRATOR, "Raid started.") end return true end diff --git a/data/scripts/talkactions/god/reload.lua b/data/scripts/talkactions/god/reload.lua index 5b294305cf3..5bf72868320 100644 --- a/data/scripts/talkactions/god/reload.lua +++ b/data/scripts/talkactions/god/reload.lua @@ -49,19 +49,17 @@ function reload.onSay(player, words, param) logCommand(player, "/reload", param) local reloadType = reloadTypes[param:lower()] - if reloadType then - saveServer() - SaveHirelings() - - Game.reload(reloadType) - logger.info("Reloaded {}", param:lower()) - - player:sendTextMessage(MESSAGE_LOOK, string.format("Reloaded %s.", param:lower())) - player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Server is saved. Now will reload configs!") - elseif not reloadType then + if not reloadType then player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Reload type not found.") - logger.warn("[reload.onSay] - Reload type '{}' not found", param) + return true end + + saveServer() + SaveHirelings() + + Game.reload(reloadType) + + player:sendTextMessage(MESSAGE_ADMINISTRATOR, string.format("The server has been reloaded, %s and configurations are now being reloaded.", param:lower())) return true end diff --git a/data/scripts/talkactions/god/save.lua b/data/scripts/talkactions/god/save.lua index 444f6ea20d2..845df50d9b4 100644 --- a/data/scripts/talkactions/god/save.lua +++ b/data/scripts/talkactions/god/save.lua @@ -16,7 +16,7 @@ function save.onSay(player, words, param) else saveServer() SaveHirelings() - player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Server has been saved.") + player:sendTextMessage(MESSAGE_ADMINISTRATOR, "Server has been saved.") end return true end diff --git a/data/scripts/talkactions/god/start_raid.lua b/data/scripts/talkactions/god/start_raid.lua index b43e77c061a..cbd3fe24a79 100644 --- a/data/scripts/talkactions/god/start_raid.lua +++ b/data/scripts/talkactions/god/start_raid.lua @@ -11,9 +11,9 @@ function startRaid.onSay(player, words, param) local returnValue = Game.startRaid(param) if returnValue ~= RETURNVALUE_NOERROR then - player:sendTextMessage(MESSAGE_ADMINISTRADOR, Game.getReturnMessage(returnValue)) + player:sendTextMessage(MESSAGE_ADMINISTRATOR, Game.getReturnMessage(returnValue)) else - player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Raid started.") + player:sendTextMessage(MESSAGE_ADMINISTRATOR, "Raid started.") end return true end diff --git a/schema.sql b/schema.sql index 1eeb78fcd14..58e6ea216ce 100644 --- a/schema.sql +++ b/schema.sql @@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS `server_config` ( CONSTRAINT `server_config_pk` PRIMARY KEY (`config`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -INSERT INTO `server_config` (`config`, `value`) VALUES ('db_version', '43'), ('motd_hash', ''), ('motd_num', '0'), ('players_record', '0'); +INSERT INTO `server_config` (`config`, `value`) VALUES ('db_version', '44'), ('motd_hash', ''), ('motd_num', '0'), ('players_record', '0'); -- Table structure `accounts` CREATE TABLE IF NOT EXISTS `accounts` ( @@ -312,9 +312,12 @@ CREATE TABLE IF NOT EXISTS `guild_wars` ( `guild2` int(11) NOT NULL DEFAULT '0', `name1` varchar(255) NOT NULL, `name2` varchar(255) NOT NULL, - `status` tinyint(2) NOT NULL DEFAULT '0', + `status` tinyint(2) UNSIGNED NOT NULL DEFAULT '0', `started` bigint(15) NOT NULL DEFAULT '0', `ended` bigint(15) NOT NULL DEFAULT '0', + `frags_limit` smallint(4) UNSIGNED NOT NULL DEFAULT '0', + `payment` bigint(13) UNSIGNED NOT NULL DEFAULT '0', + `duration_days` tinyint(3) UNSIGNED NOT NULL DEFAULT '0', INDEX `guild1` (`guild1`), INDEX `guild2` (`guild2`), CONSTRAINT `guild_wars_pk` PRIMARY KEY (`id`) diff --git a/src/config/config_enums.hpp b/src/config/config_enums.hpp index ee8b531ddcc..b9b857f435c 100644 --- a/src/config/config_enums.hpp +++ b/src/config/config_enums.hpp @@ -37,6 +37,9 @@ enum ConfigKey_t : uint16_t { CLEAN_PROTECTION_ZONES, COMBAT_CHAIN_DELAY, COMBAT_CHAIN_TARGETS, + COMBAT_CHAIN_SKILL_FORMULA_AXE, + COMBAT_CHAIN_SKILL_FORMULA_CLUB, + COMBAT_CHAIN_SKILL_FORMULA_SWORD, COMPRESSION_LEVEL, CONVERT_UNSAFE_SCRIPTS, CORE_DIRECTORY, @@ -240,6 +243,7 @@ enum ConfigKey_t : uint16_t { SCRIPTS_CONSOLE_LOGS, SERVER_MOTD, SERVER_NAME, + SHOW_LOOTS_IN_BESTIARY, SKULLED_DEATH_LOSE_STORE_ITEM, SORT_LOOT_BY_CHANCE, SQL_PORT, diff --git a/src/config/configmanager.cpp b/src/config/configmanager.cpp index 7069ca10fb2..c1702672e71 100644 --- a/src/config/configmanager.cpp +++ b/src/config/configmanager.cpp @@ -128,6 +128,7 @@ bool ConfigManager::load() { loadBoolConfig(L, REPLACE_KICK_ON_LOGIN, "replaceKickOnLogin", true); loadBoolConfig(L, REWARD_CHEST_COLLECT_ENABLED, "rewardChestCollectEnabled", true); loadBoolConfig(L, SCRIPTS_CONSOLE_LOGS, "showScriptsLogInConsole", true); + loadBoolConfig(L, SHOW_LOOTS_IN_BESTIARY, "showLootsInBestiary", false); loadBoolConfig(L, SKULLED_DEATH_LOSE_STORE_ITEM, "skulledDeathLoseStoreItem", false); loadBoolConfig(L, SORT_LOOT_BY_CHANCE, "sortLootByChance", false); loadBoolConfig(L, STAMINA_PZ, "staminaPz", false); @@ -217,6 +218,9 @@ bool ConfigManager::load() { loadIntConfig(L, CHECK_EXPIRED_MARKET_OFFERS_EACH_MINUTES, "checkExpiredMarketOffersEachMinutes", 60); loadIntConfig(L, COMBAT_CHAIN_DELAY, "combatChainDelay", 50); loadIntConfig(L, COMBAT_CHAIN_TARGETS, "combatChainTargets", 5); + loadFloatConfig(L, COMBAT_CHAIN_SKILL_FORMULA_AXE, "combatChainSkillFormulaAxe", 0.9); + loadFloatConfig(L, COMBAT_CHAIN_SKILL_FORMULA_CLUB, "combatChainSkillFormulaClub", 0.7); + loadFloatConfig(L, COMBAT_CHAIN_SKILL_FORMULA_SWORD, "combatChainSkillFormulaSword", 1.1); loadIntConfig(L, COMPRESSION_LEVEL, "packetCompressionLevel", 6); loadIntConfig(L, CRITICALCHANCE, "criticalChance", 10); loadIntConfig(L, DAY_KILLS_TO_RED, "dayKillsToRedSkull", 3); diff --git a/src/creatures/combat/combat.cpp b/src/creatures/combat/combat.cpp index 7456f572938..532f4d48bb1 100644 --- a/src/creatures/combat/combat.cpp +++ b/src/creatures/combat/combat.cpp @@ -524,7 +524,7 @@ bool Combat::setCallback(CallBackParam_t key) { void Combat::setChainCallback(uint8_t chainTargets, uint8_t chainDistance, bool backtracking) { params.chainCallback = std::make_unique(chainTargets, chainDistance, backtracking); - g_logger().debug("ChainCallback created: {}, with targets: {}, distance: {}, backtracking: {}", params.chainCallback != nullptr, chainTargets, chainDistance, backtracking); + g_logger().trace("ChainCallback created: {}, with targets: {}, distance: {}, backtracking: {}", params.chainCallback != nullptr, chainTargets, chainDistance, backtracking); } CallBack* Combat::getCallback(CallBackParam_t key) { @@ -941,6 +941,15 @@ void Combat::setupChain(const std::shared_ptr &weapon) { return; } + if (weapon->isChainDisabled()) { + return; + } + + const auto &weaponType = weapon->getWeaponType(); + if (weaponType == WEAPON_NONE || weaponType == WEAPON_SHIELD || weaponType == WEAPON_AMMO || weaponType == WEAPON_DISTANCE) { + return; + } + // clang-format off static std::list areaList = { 0, 0, 0, 1, 0, 0, 0, @@ -957,7 +966,6 @@ void Combat::setupChain(const std::shared_ptr &weapon) { setArea(area); g_logger().trace("Weapon: {}, element type: {}", Item::items[weapon->getID()].name, weapon->params.combatType); setParam(COMBAT_PARAM_TYPE, weapon->params.combatType); - const auto &weaponType = weapon->getWeaponType(); if (weaponType != WEAPON_WAND) { setParam(COMBAT_PARAM_BLOCKARMOR, true); } @@ -976,15 +984,13 @@ void Combat::setupChain(const std::shared_ptr &weapon) { switch (weaponType) { case WEAPON_SWORD: - setCommonValues(1.1, MELEE_ATK_SWORD, CONST_ME_SLASH); + setCommonValues(g_configManager().getFloat(COMBAT_CHAIN_SKILL_FORMULA_SWORD, __FUNCTION__), MELEE_ATK_SWORD, CONST_ME_SLASH); break; - case WEAPON_CLUB: - setCommonValues(0.7, MELEE_ATK_CLUB, CONST_ME_BLACK_BLOOD); + setCommonValues(g_configManager().getFloat(COMBAT_CHAIN_SKILL_FORMULA_CLUB, __FUNCTION__), MELEE_ATK_CLUB, CONST_ME_BLACK_BLOOD); break; - case WEAPON_AXE: - setCommonValues(0.9, MELEE_ATK_AXE, CONST_ANI_WHIRLWINDAXE); + setCommonValues(g_configManager().getFloat(COMBAT_CHAIN_SKILL_FORMULA_AXE, __FUNCTION__), MELEE_ATK_AXE, CONST_ANI_WHIRLWINDAXE); break; } diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index 7cf6b6bcaf3..6dd304e90ba 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -2190,7 +2190,7 @@ void Player::onThink(uint32_t interval) { } else if (client && idleTime == 60000 * kickAfterMinutes) { std::ostringstream ss; ss << "There was no variation in your behaviour for " << kickAfterMinutes << " minutes. You will be disconnected in one minute if there is no change in your actions until then."; - client->sendTextMessage(TextMessage(MESSAGE_ADMINISTRADOR, ss.str())); + client->sendTextMessage(TextMessage(MESSAGE_ADMINISTRATOR, ss.str())); } } @@ -8074,3 +8074,13 @@ void Player::checkAndShowBlessingMessage() { sendTextMessage(MESSAGE_EVENT_ADVANCE, blessOutput.str()); } } + +bool Player::canSpeakWithHireling(uint8_t speechbubble) { + const auto &playerTile = getTile(); + const auto &house = playerTile ? playerTile->getHouse() : nullptr; + if (speechbubble == SPEECHBUBBLE_HIRELING && (!house || house->getHouseAccessLevel(static_self_cast()) == HOUSE_NOT_INVITED)) { + return false; + } + + return true; +} diff --git a/src/creatures/players/player.hpp b/src/creatures/players/player.hpp index d37214911f3..592db179071 100644 --- a/src/creatures/players/player.hpp +++ b/src/creatures/players/player.hpp @@ -2595,6 +2595,8 @@ class Player final : public Creature, public Cylinder, public Bankable { std::shared_ptr getStoreInbox() const; + bool canSpeakWithHireling(uint8_t speechbubble); + private: friend class PlayerLock; std::mutex mutex; diff --git a/src/game/game.cpp b/src/game/game.cpp index c17f16b1a17..ab39f632457 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -5691,7 +5691,7 @@ void Game::playerChangeOutfit(uint32_t playerId, Outfit_t outfit, uint8_t isMoun return; } - if (playerTile->hasFlag(TILESTATE_PROTECTIONZONE)) { + if (!g_configManager().getBoolean(TOGGLE_MOUNT_IN_PZ, __FUNCTION__) && playerTile->hasFlag(TILESTATE_PROTECTIONZONE)) { outfit.lookMount = 0; } @@ -5908,6 +5908,10 @@ void Game::playerSpeakToNpc(std::shared_ptr player, const std::string &t } for (const auto &spectator : Spectators().find(player->getPosition()).filter()) { + if (!player->canSpeakWithHireling(spectator->getNpc()->getSpeechBubble())) { + continue; + } + spectator->getNpc()->onCreatureSay(player, TALKTYPE_PRIVATE_PN, text); } @@ -8452,6 +8456,16 @@ void Game::playerNpcGreet(uint32_t playerId, uint32_t npcId) { return; } + // Check npc say exhausted + if (player->isUIExhausted()) { + player->sendCancelMessage(RETURNVALUE_YOUAREEXHAUSTED); + return; + } + + if (!player->canSpeakWithHireling(npc->getSpeechBubble())) { + return; + } + auto spectators = Spectators().find(player->getPosition(), true); spectators.insert(npc); internalCreatureSay(player, TALKTYPE_SAY, "hi", false, &spectators); @@ -8463,6 +8477,8 @@ void Game::playerNpcGreet(uint32_t playerId, uint32_t npcId) { } else { internalCreatureSay(player, TALKTYPE_PRIVATE_PN, "sail", false, &npcsSpectators); } + + player->updateUIExhausted(); } void Game::playerLeaveMarket(uint32_t playerId) { diff --git a/src/io/ioguild.cpp b/src/io/ioguild.cpp index 115d688c89a..99e1e750676 100644 --- a/src/io/ioguild.cpp +++ b/src/io/ioguild.cpp @@ -60,7 +60,7 @@ uint32_t IOGuild::getGuildIdByName(const std::string &name) { void IOGuild::getWarList(uint32_t guildId, GuildWarVector &guildWarVector) { std::ostringstream query; - query << "SELECT `guild1`, `guild2` FROM `guild_wars` WHERE (`guild1` = " << guildId << " OR `guild2` = " << guildId << ") AND `ended` = 0 AND `status` = 1"; + query << "SELECT `guild1`, `guild2` FROM `guild_wars` WHERE (`guild1` = " << guildId << " OR `guild2` = " << guildId << ") AND `status` = 1"; DBResult_ptr result = Database::getInstance().storeQuery(query.str()); if (!result) { diff --git a/src/items/functions/item/item_parse.cpp b/src/items/functions/item/item_parse.cpp index 365cda202ce..a6255983f67 100644 --- a/src/items/functions/item/item_parse.cpp +++ b/src/items/functions/item/item_parse.cpp @@ -1165,9 +1165,14 @@ void ItemParse::createAndRegisterScript(ItemType &itemType, pugi::xml_node attri g_logger().warn("[{}] - wandtype '{}' does not exist", __FUNCTION__, elementName); } } else if (stringKey == "chain" && weapon) { - auto value = subValueAttribute.as_double(); - weapon->setChainSkillValue(value); - g_logger().trace("Found chain skill value '{}' for weapon: {}", value, itemType.name); + if (auto value = subValueAttribute.as_double()) { + weapon->setChainSkillValue(value); + g_logger().trace("Found chain skill value '{}' for weapon: {}", value, itemType.name); + } + if (subValueAttribute.as_bool() == false) { + weapon->setDisabledChain(); + g_logger().warn("Chain disabled for weapon: {}", itemType.name); + } } } diff --git a/src/items/weapons/weapons.cpp b/src/items/weapons/weapons.cpp index 25287ca9f92..aa90fda6c2d 100644 --- a/src/items/weapons/weapons.cpp +++ b/src/items/weapons/weapons.cpp @@ -221,9 +221,10 @@ void Weapon::internalUseWeapon(std::shared_ptr player, std::shared_ptr player, std::shared_ptrdoCombatChain(player, target, params.aggressive); } else { Combat::doCombatHealth(player, target, damage, params); } + g_logger().debug("Weapon::internalUseWeapon - cpp callback executed."); } diff --git a/src/items/weapons/weapons.hpp b/src/items/weapons/weapons.hpp index 2cf97568aef..5b2b260e2ee 100644 --- a/src/items/weapons/weapons.hpp +++ b/src/items/weapons/weapons.hpp @@ -192,6 +192,14 @@ class Weapon : public Script { return m_chainSkillValue; } + void setDisabledChain() { + m_isDisabledChain = true; + } + + bool isChainDisabled() const { + return m_isDisabledChain; + } + const WeaponType_t getWeaponType() const { return weaponType; } @@ -243,6 +251,7 @@ class Weapon : public Script { bool enabled = true; bool premium = false; bool wieldUnproperly = false; + bool m_isDisabledChain = false; std::string vocationString = ""; void onUsedWeapon(std::shared_ptr player, std::shared_ptr item, std::shared_ptr destTile) const; diff --git a/src/lua/functions/core/game/lua_enums.cpp b/src/lua/functions/core/game/lua_enums.cpp index 66b7cf1feec..2e3813e0769 100644 --- a/src/lua/functions/core/game/lua_enums.cpp +++ b/src/lua/functions/core/game/lua_enums.cpp @@ -742,7 +742,7 @@ void LuaEnums::initGameStateEnums(lua_State* L) { void LuaEnums::initMessageEnums(lua_State* L) { registerEnum(L, MESSAGE_GAMEMASTER_CONSOLE); registerEnum(L, MESSAGE_LOGIN); - registerEnum(L, MESSAGE_ADMINISTRADOR); + registerEnum(L, MESSAGE_ADMINISTRATOR); registerEnum(L, MESSAGE_EVENT_ADVANCE); registerEnum(L, MESSAGE_GAME_HIGHLIGHT); registerEnum(L, MESSAGE_FAILURE); diff --git a/src/lua/functions/core/libs/logger_functions.cpp b/src/lua/functions/core/libs/logger_functions.cpp index dc039a9ed0d..1b2605f6421 100644 --- a/src/lua/functions/core/libs/logger_functions.cpp +++ b/src/lua/functions/core/libs/logger_functions.cpp @@ -24,6 +24,7 @@ void LoggerFunctions::init(lua_State* L) { registerMethod(L, "logger", "warn", LoggerFunctions::luaLoggerWarn); registerMethod(L, "logger", "error", LoggerFunctions::luaLoggerError); registerMethod(L, "logger", "debug", LoggerFunctions::luaLoggerDebug); + registerMethod(L, "logger", "trace", LoggerFunctions::luaLoggerTrace); } int LoggerFunctions::luaSpdlogInfo(lua_State* L) { @@ -107,3 +108,13 @@ int LoggerFunctions::luaLoggerDebug(lua_State* L) { } return 1; } + +int LoggerFunctions::luaLoggerTrace(lua_State* L) { + // logger.trace(text) + if (isString(L, 1)) { + g_logger().trace(getFormatedLoggerMessage(L)); + } else { + reportErrorFunc("First parameter needs to be a string"); + } + return 1; +} diff --git a/src/lua/functions/core/libs/logger_functions.hpp b/src/lua/functions/core/libs/logger_functions.hpp index 5e83f1461c9..2c4dba46cc1 100644 --- a/src/lua/functions/core/libs/logger_functions.hpp +++ b/src/lua/functions/core/libs/logger_functions.hpp @@ -25,4 +25,5 @@ class LoggerFunctions final : public LuaScriptInterface { static int luaLoggerError(lua_State* L); static int luaLoggerInfo(lua_State* L); static int luaLoggerWarn(lua_State* L); + static int luaLoggerTrace(lua_State* L); }; diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index 566f39c7e71..43fa9046cbb 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -2334,10 +2334,10 @@ void ProtocolGame::parseBestiarysendMonsterData(NetworkMessage &msg) { break; } - newmsg.add(shouldAddItem == true ? loot.id : 0); + newmsg.add(g_configManager().getBoolean(SHOW_LOOTS_IN_BESTIARY, __FUNCTION__) || shouldAddItem == true ? loot.id : 0); newmsg.addByte(difficult); newmsg.addByte(0); // 1 if special event - 0 if regular loot (?) - if (shouldAddItem == true) { + if (g_configManager().getBoolean(SHOW_LOOTS_IN_BESTIARY, __FUNCTION__) || shouldAddItem == true) { newmsg.addString(loot.name, "ProtocolGame::parseBestiarysendMonsterData - loot.name"); newmsg.addByte(loot.countmax > 0 ? 0x1 : 0x0); } @@ -4062,7 +4062,7 @@ void ProtocolGame::sendPremiumTrigger() { void ProtocolGame::sendTextMessage(const TextMessage &message) { if (message.type == MESSAGE_NONE) { g_logger().error("[ProtocolGame::sendTextMessage] - Message type is wrong, missing or invalid for player with name {}, on position {}", player->getName(), player->getPosition().toString()); - player->sendTextMessage(MESSAGE_ADMINISTRADOR, "There was a problem requesting your message, please contact the administrator"); + player->sendTextMessage(MESSAGE_ADMINISTRATOR, "There was a problem requesting your message, please contact the administrator"); return; } diff --git a/src/utils/utils_definitions.hpp b/src/utils/utils_definitions.hpp index 59f0049ad9c..af2c40ba533 100644 --- a/src/utils/utils_definitions.hpp +++ b/src/utils/utils_definitions.hpp @@ -340,7 +340,7 @@ enum MessageClasses : uint8_t { /* Red message in the console*/ /* TALKTYPE_BROADCAST */ MESSAGE_LOGIN = 17, /* White message at the bottom of the game window and in the console*/ - MESSAGE_ADMINISTRADOR = 18, /* Red message in game window and in the console*/ + MESSAGE_ADMINISTRATOR = 18, /* Red message in game window and in the console*/ MESSAGE_EVENT_ADVANCE = 19, /* White message in game window and in the console*/ MESSAGE_GAME_HIGHLIGHT = 20, /* Red message in game window and in the console*/ MESSAGE_FAILURE = 21, /* White message at the bottom of the game window"*/