diff --git a/data-otservbr-global/lib/core/storages.lua b/data-otservbr-global/lib/core/storages.lua
index da86c8b9bb9..ba71dfedb6f 100644
--- a/data-otservbr-global/lib/core/storages.lua
+++ b/data-otservbr-global/lib/core/storages.lua
@@ -2844,6 +2844,11 @@ Storage = {
},
},
},
+ U13_20 = { -- update 13.20 - Reserved Storages 47952 - 47970
+ RottenBlood = {
+ AccessDoor = 47952,
+ },
+ },
},
-- Reserved storage from 63951 - 63999
ThaisExhibition = {
diff --git a/data-otservbr-global/monster/bosses/bakragore.lua b/data-otservbr-global/monster/bosses/bakragore.lua
new file mode 100644
index 00000000000..2a0ca5c60fc
--- /dev/null
+++ b/data-otservbr-global/monster/bosses/bakragore.lua
@@ -0,0 +1,159 @@
+local mType = Game.createMonsterType("Bakragore")
+local monster = {}
+
+monster.description = "Bakragore"
+monster.experience = 15000000
+monster.outfit = {
+ lookType = 1671,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.events = {
+ "RottenBloodBakragoreDeath",
+}
+
+monster.bosstiary = {
+ bossRaceId = 2367,
+ bossRace = RARITY_NEMESIS,
+}
+
+monster.health = 660000
+monster.maxHealth = 660000
+monster.race = "undead"
+monster.corpse = 44012
+monster.speed = 250
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 10000,
+ chance = 20,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = true,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 98,
+ targetDistance = 1,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.summon = {
+ maxSummons = 2,
+ summons = {
+ { name = "Elder Bloodjaw", chance = 20, interval = 2000, count = 2 },
+ },
+}
+
+monster.voices = {
+ interval = 5000,
+ chance = 10,
+ { text = "Light ... darkens!", yell = false },
+ { text = "Light .. the ... darkness!", yell = false },
+ { text = "Darkness ... is ... light!", yell = false },
+ { text = "WILL ... PUNISH ... YOU!", yell = false },
+ { text = "RAAAR!", yell = false },
+}
+
+monster.loot = {
+ { name = "crystal coin", chance = 8938, maxCount = 200 },
+ { name = "supreme health potion", chance = 8938, maxCount = 300 },
+ { name = "ultimate mana potion", chance = 11433, maxCount = 300 },
+ { name = "ultimate spirit potion", chance = 11433, maxCount = 300 },
+ { name = "berserk potion", chance = 10938, maxCount = 90 },
+ { name = "bullseye potion", chance = 10938, maxCount = 90 },
+ { name = "mastermind potion", chance = 10938, maxCount = 30 },
+ { name = "blue gem", chance = 10570, maxCount = 10 },
+ { name = "giant amethyst", chance = 10570, maxCount = 10 },
+ { name = "giant emerald", chance = 10570, maxCount = 10 },
+ { name = "giant ruby", chance = 10570, maxCount = 10 },
+ { name = "red gem", chance = 10570, maxCount = 10 },
+ { name = "giant sapphire", chance = 10570, maxCount = 10 },
+ { name = "giant topaz", chance = 10570, maxCount = 10 },
+ { name = "violet gem", chance = 10970, maxCount = 10 },
+ { name = "yellow gem", chance = 10970, maxCount = 10 },
+ { name = "figurine of bakragore", chance = 10970 },
+ { name = "bakragore's amalgamation", chance = 570 },
+ { name = "spiritual horseshoe", chance = 470 },
+ { id = 43895, chance = 360 }, -- Bag you covet
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -3000 },
+ { name = "combat", interval = 3000, chance = 35, type = COMBAT_ICEDAMAGE, minDamage = -900, maxDamage = -1100, range = 7, radius = 7, shootEffect = CONST_ANI_ICE, effect = 243, target = true },
+ { name = "combat", interval = 2000, chance = 13, type = COMBAT_DEATHDAMAGE, minDamage = -100, maxDamage = -1000, length = 8, spread = 0, effect = 252, target = false },
+ { name = "combat", interval = 3000, chance = 30, type = COMBAT_FIREDAMAGE, minDamage = -1000, maxDamage = -2000, length = 8, spread = 0, effect = 249, target = false },
+ { name = "combat", interval = 2000, chance = 30, type = COMBAT_ICEDAMAGE, minDamage = -950, maxDamage = -2400, range = 7, radius = 3, shootEffect = 37, effect = 240, target = true },
+ { name = "combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -1000, maxDamage = -2500, length = 8, spread = 0, effect = 244, target = false },
+}
+
+monster.defenses = {
+ defense = 135,
+ armor = 135,
+ { name = "combat", interval = 3000, chance = 15, type = COMBAT_HEALING, minDamage = 2500, maxDamage = 3500, effect = 236, target = false },
+ { name = "speed", interval = 4000, chance = 80, speedChange = 700, effect = CONST_ME_MAGIC_RED, target = false, duration = 6000 },
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 15 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 15 },
+ { type = COMBAT_EARTHDAMAGE, percent = 15 },
+ { type = COMBAT_FIREDAMAGE, percent = 15 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 15 },
+ { type = COMBAT_HOLYDAMAGE, percent = 15 },
+ { type = COMBAT_DEATHDAMAGE, percent = 15 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType.onThink = function(monster, interval) end
+
+mType.onAppear = function(monster, creature)
+ if monster:getType():isRewardBoss() then
+ monster:setReward(true)
+ end
+end
+
+mType.onDisappear = function(monster, creature) end
+
+mType.onMove = function(monster, creature, fromPosition, toPosition) end
+
+mType.onSay = function(monster, creature, type, message) end
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/bosses/chagorz.lua b/data-otservbr-global/monster/bosses/chagorz.lua
new file mode 100644
index 00000000000..bec5b74e9e8
--- /dev/null
+++ b/data-otservbr-global/monster/bosses/chagorz.lua
@@ -0,0 +1,147 @@
+local mType = Game.createMonsterType("Chagorz")
+local monster = {}
+
+monster.description = "Chagorz"
+monster.experience = 3250000
+monster.outfit = {
+ lookType = 1665,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.events = {
+ "RottenBloodBossDeath",
+}
+
+monster.bosstiary = {
+ bossRaceId = 2366,
+ bossRace = RARITY_ARCHFOE,
+}
+
+monster.health = 350000
+monster.maxHealth = 350000
+monster.race = "undead"
+monster.corpse = 44024
+monster.speed = 250
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 10000,
+ chance = 20,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = true,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 98,
+ targetDistance = 1,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.summon = {}
+
+monster.voices = {
+ interval = 5000,
+ chance = 10,
+ { text = "The light... that... drains!", yell = false },
+ { text = "RAAAR!", yell = false },
+ { text = "WILL ... PUNISH ... YOU!", yell = false },
+ { text = "Darkness ... devours!", yell = false },
+}
+
+monster.loot = {
+ { name = "crystal coin", chance = 5441, maxCount = 108 },
+ { name = "mastermind potion", chance = 5530, maxCount = 28 },
+ { name = "supreme health potion", chance = 5044, maxCount = 154 },
+ { name = "giant sapphire", chance = 10546, maxCount = 1 },
+ { name = "ultimate mana potion", chance = 5752, maxCount = 107 },
+ { name = "violet gem", chance = 13217, maxCount = 4 },
+ { id = 3039, chance = 13465, maxCount = 1 }, -- red gem
+ { name = "yellow gem", chance = 14071, maxCount = 1 },
+ { name = "blue gem", chance = 11156, maxCount = 3 },
+ { name = "bullseye potion", chance = 6792, maxCount = 21 },
+ { name = "giant amethyst", chance = 11603, maxCount = 1 },
+ { name = "giant topaz", chance = 12280, maxCount = 1 },
+ { name = "green gem", chance = 8348, maxCount = 1 },
+ { name = "ultimate spirit potion", chance = 10934, maxCount = 18 },
+ { name = "white gem", chance = 9600, maxCount = 3 },
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = -1300, maxDamage = -2250 },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -500, maxDamage = -900, radius = 4, effect = CONST_ME_GREEN_RINGS, target = false },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -500, maxDamage = -900, range = 4, radius = 4, effect = 241, target = true },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -1000, maxDamage = -1200, length = 10, spread = 0, effect = CONST_ME_POFF, target = false },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_LIFEDRAIN, minDamage = -1500, maxDamage = -1900, length = 10, spread = 0, effect = 225, target = false },
+ { name = "speed", interval = 2000, chance = 20, speedChange = -600, radius = 7, effect = CONST_ME_MAGIC_GREEN, target = false, duration = 20000 },
+}
+
+monster.defenses = {
+ defense = 105,
+ armor = 105,
+ { name = "combat", interval = 3000, chance = 10, type = COMBAT_HEALING, minDamage = 700, maxDamage = 1500, effect = 236, target = false },
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 15 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 15 },
+ { type = COMBAT_EARTHDAMAGE, percent = 15 },
+ { type = COMBAT_FIREDAMAGE, percent = 15 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 15 },
+ { type = COMBAT_HOLYDAMAGE, percent = 15 },
+ { type = COMBAT_DEATHDAMAGE, percent = 15 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType.onThink = function(monster, interval) end
+
+mType.onAppear = function(monster, creature)
+ if monster:getType():isRewardBoss() then
+ monster:setReward(true)
+ end
+end
+
+mType.onDisappear = function(monster, creature) end
+
+mType.onMove = function(monster, creature, fromPosition, toPosition) end
+
+mType.onSay = function(monster, creature, type, message) end
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/bosses/ichgahal.lua b/data-otservbr-global/monster/bosses/ichgahal.lua
new file mode 100644
index 00000000000..7d0d21924e4
--- /dev/null
+++ b/data-otservbr-global/monster/bosses/ichgahal.lua
@@ -0,0 +1,154 @@
+local mType = Game.createMonsterType("Ichgahal")
+local monster = {}
+
+monster.description = "Ichgahal"
+monster.experience = 3250000
+monster.outfit = {
+ lookType = 1665,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.events = {
+ "RottenBloodBossDeath",
+}
+
+monster.bosstiary = {
+ bossRaceId = 2364,
+ bossRace = RARITY_NEMESIS,
+}
+
+monster.health = 350000
+monster.maxHealth = 350000
+monster.race = "undead"
+monster.corpse = 44018
+monster.speed = 250
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 10000,
+ chance = 20,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = true,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 98,
+ targetDistance = 1,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.summon = {
+ maxSummons = 8,
+ summons = {
+ { name = "Mushroom", chance = 30, interval = 5000, count = 8 },
+ },
+}
+
+monster.voices = {
+ interval = 5000,
+ chance = 10,
+ { text = "Rott!!", yell = false },
+ { text = "Putrefy!", yell = false },
+ { text = "Decay!", yell = false },
+}
+
+monster.loot = {
+ { name = "crystal coin", chance = 14615, maxCount = 115 },
+ { name = "ultimate spirit potion", chance = 7169, maxCount = 153 },
+ { name = "mastermind potion", chance = 14651, maxCount = 45 },
+ { name = "yellow gem", chance = 9243, maxCount = 5 },
+ { name = "amber with a bug", chance = 7224, maxCount = 2 },
+ { name = "ultimate mana potion", chance = 13137, maxCount = 179 },
+ { name = "violet gem", chance = 14447, maxCount = 4 },
+ { name = "raw watermelon tourmaline", chance = 6788, maxCount = 2 },
+ { id = 3039, chance = 9047, maxCount = 1 }, -- red gem
+ { name = "supreme health potion", chance = 14635, maxCount = 37 },
+ { name = "berserk potion", chance = 14973, maxCount = 45 },
+ { name = "amber with a dragonfly", chance = 6470, maxCount = 1 },
+ { name = "gold ingot", chance = 11421, maxCount = 1 },
+ { name = "blue gem", chance = 8394, maxCount = 1 },
+ { name = "bullseye potion", chance = 13783, maxCount = 36 },
+ { name = "putrefactive figurine", chance = 11416, maxCount = 1 },
+ { name = "ichgahal's fungal infestation", chance = 7902, maxCount = 1 },
+ { name = "white gem", chance = 13559, maxCount = 3 },
+ { id = 43895, chance = 360 }, -- Bag you covet
+}
+
+monster.attacks = {
+ { name = "melee", interval = 3000, chance = 100, minDamage = -1500, maxDamage = -2300 },
+ { name = "combat", interval = 1000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = -700, maxDamage = -1000, length = 12, spread = 0, effect = 249, target = false },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_MANADRAIN, minDamage = -2600, maxDamage = -2300, length = 12, spread = 0, effect = 193, target = false },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -900, maxDamage = -1500, length = 6, spread = 0, effect = CONST_ME_FIREAREA, target = false },
+ { name = "speed", interval = 2000, chance = 35, speedChange = -600, radius = 8, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000 },
+}
+
+monster.defenses = {
+ defense = 105,
+ armor = 105,
+ { name = "combat", interval = 3000, chance = 10, type = COMBAT_HEALING, minDamage = 800, maxDamage = 1200, effect = 236, target = false },
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 15 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 15 },
+ { type = COMBAT_EARTHDAMAGE, percent = 15 },
+ { type = COMBAT_FIREDAMAGE, percent = 15 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 15 },
+ { type = COMBAT_HOLYDAMAGE, percent = 15 },
+ { type = COMBAT_DEATHDAMAGE, percent = 15 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType.onThink = function(monster, interval) end
+
+mType.onAppear = function(monster, creature)
+ if monster:getType():isRewardBoss() then
+ monster:setReward(true)
+ end
+end
+
+mType.onDisappear = function(monster, creature) end
+
+mType.onMove = function(monster, creature, fromPosition, toPosition) end
+
+mType.onSay = function(monster, creature, type, message) end
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/bosses/murcion.lua b/data-otservbr-global/monster/bosses/murcion.lua
new file mode 100644
index 00000000000..ad091f74758
--- /dev/null
+++ b/data-otservbr-global/monster/bosses/murcion.lua
@@ -0,0 +1,140 @@
+local mType = Game.createMonsterType("Murcion")
+local monster = {}
+
+monster.description = "Murcion"
+monster.experience = 3250000
+monster.outfit = {
+ lookType = 1664,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.events = {
+ "RottenBloodBossDeath",
+}
+
+monster.bosstiary = {
+ bossRaceId = 2362,
+ bossRace = RARITY_NEMESIS,
+}
+
+monster.health = 350000
+monster.maxHealth = 350000
+monster.race = "undead"
+monster.corpse = 44015
+monster.speed = 250
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 10000,
+ chance = 20,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = true,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 98,
+ targetDistance = 1,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.summon = {
+ maxSummons = 8,
+ summons = {
+ { name = "Mushroom", chance = 30, interval = 5000, count = 8 },
+ },
+}
+
+monster.voices = {}
+
+monster.loot = {
+ { name = "crystal coin", chance = 12317, maxCount = 91 },
+ { id = 3039, chance = 10896, maxCount = 2 }, -- red gem
+ { name = "amber with a bug", chance = 14590, maxCount = 1 },
+ { name = "amber with a dragonfly", chance = 5405, maxCount = 1 },
+ { name = "bullseye potion", chance = 10821, maxCount = 44 },
+ { name = "green gem", chance = 7763, maxCount = 4 },
+ { name = "mastermind potion", chance = 9534, maxCount = 15 },
+ { name = "supreme health potion", chance = 6212, maxCount = 102 },
+ { name = "ultimate mana potion", chance = 8785, maxCount = 29 },
+ { name = "ultimate spirit potion", chance = 8783, maxCount = 161 },
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = -1400, maxDamage = -2300 },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -500, maxDamage = -900, radius = 4, effect = CONST_ME_SMALLCLOUDS, target = false },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_HOLYDAMAGE, minDamage = -500, maxDamage = -900, range = 4, radius = 4, shootEffect = 31, effect = 248, target = true },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_ICEDAMAGE, minDamage = -1000, maxDamage = -1200, length = 10, spread = 0, effect = 53, target = false },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -1500, maxDamage = -1900, length = 10, spread = 0, effect = 158, target = false },
+ { name = "speed", interval = 2000, chance = 20, speedChange = -600, radius = 7, effect = CONST_ME_POFF, target = false, duration = 20000 },
+}
+
+monster.defenses = {
+ defense = 105,
+ armor = 105,
+ { name = "combat", interval = 3000, chance = 10, type = COMBAT_HEALING, minDamage = 800, maxDamage = 1500, effect = 236, target = false },
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 15 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 15 },
+ { type = COMBAT_EARTHDAMAGE, percent = 15 },
+ { type = COMBAT_FIREDAMAGE, percent = 15 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 15 },
+ { type = COMBAT_HOLYDAMAGE, percent = 15 },
+ { type = COMBAT_DEATHDAMAGE, percent = 15 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType.onThink = function(monster, interval) end
+
+mType.onAppear = function(monster, creature)
+ if monster:getType():isRewardBoss() then
+ monster:setReward(true)
+ end
+end
+
+mType.onDisappear = function(monster, creature) end
+
+mType.onMove = function(monster, creature, fromPosition, toPosition) end
+
+mType.onSay = function(monster, creature, type, message) end
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/bosses/vemiath.lua b/data-otservbr-global/monster/bosses/vemiath.lua
new file mode 100644
index 00000000000..97be142a621
--- /dev/null
+++ b/data-otservbr-global/monster/bosses/vemiath.lua
@@ -0,0 +1,151 @@
+local mType = Game.createMonsterType("Vemiath")
+local monster = {}
+
+monster.description = "Vemiath"
+monster.experience = 3250000
+monster.outfit = {
+ lookType = 1665,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.events = {
+ "RottenBloodBossDeath",
+}
+
+monster.bosstiary = {
+ bossRaceId = 2365,
+ bossRace = RARITY_ARCHFOE,
+}
+
+monster.health = 350000
+monster.maxHealth = 350000
+monster.race = "undead"
+monster.corpse = 44021
+monster.speed = 250
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 10000,
+ chance = 20,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = true,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 98,
+ targetDistance = 1,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.summon = {}
+
+monster.voices = {
+ interval = 5000,
+ chance = 10,
+ { text = "The light... that... drains!", yell = false },
+ { text = "RAAAR!", yell = false },
+ { text = "WILL ... PUNISH ... YOU!", yell = false },
+ { text = "Darkness ... devours!", yell = false },
+}
+
+monster.loot = {
+ { name = "crystal coin", chance = 8852, maxCount = 125 },
+ { name = "ultimate mana potion", chance = 11337, maxCount = 211 },
+ { name = "giant emerald", chance = 6423, maxCount = 1 },
+ { name = "supreme health potion", chance = 8385, maxCount = 179 },
+ { name = "yellow gem", chance = 8604, maxCount = 5 },
+ { name = "berserk potion", chance = 9395, maxCount = 45 },
+ { name = "blue gem", chance = 14144, maxCount = 5 },
+ { name = "green gem", chance = 6221, maxCount = 4 },
+ { name = "bullseye potion", chance = 6530, maxCount = 26 },
+ { name = "mastermind potion", chance = 5700, maxCount = 44 },
+ { name = "ultimate spirit potion", chance = 9216, maxCount = 25 },
+ { name = "giant topaz", chance = 11191, maxCount = 1 },
+ { name = "giant amethyst", chance = 8527, maxCount = 1 },
+ { name = "gold ingot", chance = 10866, maxCount = 1 },
+ { id = 3039, chance = 8945, maxCount = 1 }, -- red gem
+ { name = "dragon figurine", chance = 11502, maxCount = 1 },
+ { name = "raw watermelon tourmaline", chance = 9302, maxCount = 1 },
+ { name = "vemiath's infused basalt", chance = 7914, maxCount = 1 },
+ { name = "violet gem", chance = 7210, maxCount = 1 },
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = -1500, maxDamage = -2500 },
+ { name = "combat", interval = 3000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -1000, length = 10, spread = 3, effect = 244, target = false },
+ { name = "speed", interval = 2000, chance = 25, speedChange = -600, radius = 7, effect = CONST_ME_MAGIC_RED, target = false, duration = 15000 },
+ { name = "combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -300, maxDamage = -700, radius = 5, effect = 243, target = false },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_DEATHDAMAGE, minDamage = -500, maxDamage = -800, length = 10, spread = 3, effect = CONST_ME_EXPLOSIONHIT, target = false },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -500, maxDamage = -800, length = 8, spread = 3, effect = CONST_ME_FIREATTACK, target = false },
+}
+
+monster.defenses = {
+ defense = 105,
+ armor = 105,
+ { name = "combat", interval = 3000, chance = 10, type = COMBAT_HEALING, minDamage = 800, maxDamage = 1500, effect = 236, target = false },
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 15 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 15 },
+ { type = COMBAT_EARTHDAMAGE, percent = 15 },
+ { type = COMBAT_FIREDAMAGE, percent = 15 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 15 },
+ { type = COMBAT_HOLYDAMAGE, percent = 15 },
+ { type = COMBAT_DEATHDAMAGE, percent = 15 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType.onThink = function(monster, interval) end
+
+mType.onAppear = function(monster, creature)
+ if monster:getType():isRewardBoss() then
+ monster:setReward(true)
+ end
+end
+
+mType.onDisappear = function(monster, creature) end
+
+mType.onMove = function(monster, creature, fromPosition, toPosition) end
+
+mType.onSay = function(monster, creature, type, message) end
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/bloated_man-maggot.lua b/data-otservbr-global/monster/quests/rotten_blood/bloated_man-maggot.lua
new file mode 100644
index 00000000000..76c2ecb9fb3
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/bloated_man-maggot.lua
@@ -0,0 +1,122 @@
+local mType = Game.createMonsterType("Bloated Man-Maggot")
+local monster = {}
+
+monster.description = "a bloated man-maggot"
+monster.experience = 21570
+monster.outfit = {
+ lookType = 1654,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.raceId = 2392
+monster.Bestiary = {
+ class = "Vermin",
+ race = BESTY_RACE_VERMIN,
+ toKill = 5000,
+ FirstUnlock = 200,
+ SecondUnlock = 2000,
+ CharmsPoints = 100,
+ Stars = 5,
+ Occurrence = 0,
+ Locations = "Jaded Roots",
+}
+
+monster.health = 31700
+monster.maxHealth = 31700
+monster.race = "undead"
+monster.corpse = 43816
+monster.speed = 195
+monster.manaCost = 305
+
+monster.changeTarget = {
+ interval = 5000,
+ chance = 10,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = true,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 90,
+ targetDistance = 1,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.voices = {}
+
+monster.loot = {
+ { name = "crystal coin", chance = 12961, maxCount = 1 },
+ { name = "organic acid", chance = 11678, maxCount = 1 },
+ { name = "might ring", chance = 10020, maxCount = 1 },
+ { name = "small emerald", chance = 9133, maxCount = 5 },
+ { name = "rotten roots", chance = 8637, maxCount = 1 },
+ { name = "bloated maggot", chance = 8133, maxCount = 1 },
+ { name = "terra rod", chance = 8078, maxCount = 1 },
+ { name = "butcher's axe", chance = 7967, maxCount = 1 },
+ { name = "blue gem", chance = 7808, maxCount = 1 },
+ { name = "violet gem", chance = 7084, maxCount = 1 },
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1500 },
+ { name = "combat", interval = 2500, chance = 25, type = COMBAT_PHYSICALDAMAGE, minDamage = -1400, maxDamage = -1700, radius = 5, effect = CONST_ME_GHOSTLY_BITE, target = true },
+ { name = "combat", interval = 2500, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -1400, maxDamage = -1900, radius = 5, effect = CONST_ME_BIGPLANTS, target = false },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -1400, maxDamage = -1550, length = 8, spread = 3, effect = CONST_ME_GROUNDSHAKER, target = false },
+ { name = "largefirering", interval = 2500, chance = 15, minDamage = -1400, maxDamage = -1800, target = false },
+}
+
+monster.defenses = {
+ defense = 104,
+ armor = 104,
+ mitigation = 3.16,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 45 },
+ { type = COMBAT_ENERGYDAMAGE, percent = -15 },
+ { type = COMBAT_EARTHDAMAGE, percent = 40 },
+ { type = COMBAT_FIREDAMAGE, percent = 15 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = -15 },
+ { type = COMBAT_HOLYDAMAGE, percent = -5 },
+ { type = COMBAT_DEATHDAMAGE, percent = 5 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = false },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/converter.lua b/data-otservbr-global/monster/quests/rotten_blood/converter.lua
new file mode 100644
index 00000000000..65ebab91985
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/converter.lua
@@ -0,0 +1,119 @@
+local mType = Game.createMonsterType("Converter")
+local monster = {}
+
+monster.description = "a converter"
+monster.experience = 21425
+monster.outfit = {
+ lookType = 1623,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.raceId = 2379
+monster.Bestiary = {
+ class = "Elemental",
+ race = BESTY_RACE_ELEMENTAL,
+ toKill = 5000,
+ FirstUnlock = 200,
+ SecondUnlock = 2000,
+ CharmsPoints = 100,
+ Stars = 5,
+ Occurrence = 0,
+ Locations = "Gloom Pillars.",
+}
+
+monster.health = 29600
+monster.maxHealth = 29600
+monster.race = "undead"
+monster.corpse = 43567
+monster.speed = 250
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 4000,
+ chance = 10,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = true,
+ canPushItems = true,
+ canPushCreatures = false,
+ staticAttackChance = 80,
+ targetDistance = 1,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = false,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.loot = {
+ { name = "crystal coin", chance = 5230, maxCount = 1 },
+ { name = "darklight obsidian axe", chance = 6963, maxCount = 1 },
+ { name = "darklight matter", chance = 6927, maxCount = 1 },
+ { name = "darklight core", chance = 10715, maxCount = 1 },
+ { name = "wand of starstorm", chance = 8797, maxCount = 1 },
+ { name = "blue gem", chance = 9372, maxCount = 1 },
+ { name = "ultimate health potion", chance = 9851, maxCount = 5 },
+ { name = "focus cape", chance = 6945, maxCount = 1 },
+ { name = "white gem", chance = 14533, maxCount = 1 },
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -900 },
+ { name = "combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -1400, maxDamage = -1900, length = 7, spread = 0, effect = CONST_ME_PINK_ENERGY_SPARK, target = false },
+ { name = "combat", interval = 2500, chance = 20, type = COMBAT_HOLYDAMAGE, minDamage = -1500, maxDamage = -1600, radius = 5, effect = CONST_ME_GHOSTLY_BITE, target = true },
+ { name = "largeholyring", interval = 2000, chance = 15, minDamage = -1400, maxDamage = -1900 },
+ { name = "energy chain", interval = 3200, chance = 20, minDamage = -800, maxDamage = -1200 },
+}
+
+monster.defenses = {
+ defense = 100,
+ armor = 100,
+ mitigation = 3.31,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = -20 },
+ { type = COMBAT_ENERGYDAMAGE, percent = -10 },
+ { type = COMBAT_EARTHDAMAGE, percent = 10 },
+ { type = COMBAT_FIREDAMAGE, percent = 25 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 0 },
+ { type = COMBAT_HOLYDAMAGE, percent = 35 },
+ { type = COMBAT_DEATHDAMAGE, percent = -15 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/darklight_construct.lua b/data-otservbr-global/monster/quests/rotten_blood/darklight_construct.lua
new file mode 100644
index 00000000000..c4b2c5e8568
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/darklight_construct.lua
@@ -0,0 +1,120 @@
+local mType = Game.createMonsterType("Darklight Construct")
+local monster = {}
+
+monster.description = "a darklight construct"
+monster.experience = 22050
+monster.outfit = {
+ lookType = 1622,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.raceId = 2378
+monster.Bestiary = {
+ class = "Magical",
+ race = BESTY_RACE_MAGICAL,
+ toKill = 5000,
+ FirstUnlock = 200,
+ SecondUnlock = 2000,
+ CharmsPoints = 100,
+ Stars = 5,
+ Occurrence = 0,
+ Locations = "Darklight Core",
+}
+
+monster.health = 32200
+monster.maxHealth = 32200
+monster.race = "undead"
+monster.corpse = 43840
+monster.speed = 220
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 4000,
+ chance = 10,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 90,
+ targetDistance = 0,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.loot = {
+ { name = "crystal coin", chance = 11290, maxCount = 1 },
+ { name = "dark obsidian splinter", chance = 12735, maxCount = 1 },
+ { id = 3039, chance = 8781, maxCount = 1 }, -- red gem
+ { name = "small emerald", chance = 6646, maxCount = 3 },
+ { name = "zaoan shoes", chance = 8614, maxCount = 1 },
+ { name = "darklight core", chance = 5659, maxCount = 1 },
+ { name = "darklight obsidian axe", chance = 11129, maxCount = 1 },
+ { name = "magma amulet", chance = 13240, maxCount = 1 },
+ { name = "small ruby", chance = 12458, maxCount = 3 },
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1050 },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -1300, maxDamage = -1500, length = 8, spread = 3, effect = CONST_ME_HITBYFIRE, target = false },
+ { name = "combat", interval = 2000, chance = 25, type = COMBAT_FIREDAMAGE, minDamage = -1100, maxDamage = -1400, radius = 5, effect = CONST_ME_HITBYFIRE, target = false },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_HOLYDAMAGE, minDamage = -1500, maxDamage = -1600, radius = 5, effect = CONST_ME_HOLYAREA, target = true },
+ { name = "extended fire chain", interval = 2000, chance = 15, minDamage = -800, maxDamage = -1200, target = true },
+ { name = "largefirering", interval = 2800, chance = 20, minDamage = -1000, maxDamage = -1300, target = false },
+}
+
+monster.defenses = {
+ defense = 117,
+ armor = 117,
+ mitigation = 2.98,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = -15 },
+ { type = COMBAT_ENERGYDAMAGE, percent = -5 },
+ { type = COMBAT_EARTHDAMAGE, percent = 10 },
+ { type = COMBAT_FIREDAMAGE, percent = 55 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = -5 },
+ { type = COMBAT_HOLYDAMAGE, percent = 40 },
+ { type = COMBAT_DEATHDAMAGE, percent = -20 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/darklight_emitter.lua b/data-otservbr-global/monster/quests/rotten_blood/darklight_emitter.lua
new file mode 100644
index 00000000000..dc211745db4
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/darklight_emitter.lua
@@ -0,0 +1,118 @@
+local mType = Game.createMonsterType("Darklight Emitter")
+local monster = {}
+
+monster.description = "a darklight emitter"
+monster.experience = 20600
+monster.outfit = {
+ lookType = 1627,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.raceId = 2382
+monster.Bestiary = {
+ class = "Magical",
+ race = BESTY_RACE_MAGICAL,
+ toKill = 5000,
+ FirstUnlock = 200,
+ SecondUnlock = 2000,
+ CharmsPoints = 100,
+ Stars = 5,
+ Occurrence = 0,
+ Locations = "Darklight Core",
+}
+
+monster.health = 27500
+monster.maxHealth = 27500
+monster.race = "undead"
+monster.corpse = 43583
+monster.speed = 210
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 4000,
+ chance = 10,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 90,
+ targetDistance = 0,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.loot = {
+ { name = "crystal coin", chance = 12516, maxCount = 2 },
+ { name = "darklight core", chance = 13367, maxCount = 1 },
+ { name = "darklight obsidian axe", chance = 10433, maxCount = 1 },
+ { name = "zaoan armor", chance = 8574, maxCount = 1 },
+ { name = "basalt crumbs", chance = 5794, maxCount = 1 },
+ { name = "small topaz", chance = 5784, maxCount = 3 },
+ { name = "amber staff", chance = 6240, maxCount = 1 },
+ { id = 3039, chance = 8459, maxCount = 1 }, -- red gem
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1050 },
+ { name = "combat", interval = 2600, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -1400, maxDamage = -1750, length = 8, spread = 3, effect = CONST_ME_HITBYFIRE, target = false },
+ { name = "combat", interval = 3100, chance = 20, type = COMBAT_HOLYDAMAGE, minDamage = -1000, maxDamage = -1600, length = 8, spread = 3, effect = CONST_ME_HOLYAREA, target = false },
+ { name = "combat", interval = 2600, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -1200, maxDamage = -1650, radius = 5, effect = CONST_ME_HITBYFIRE, target = true },
+ { name = "largefirering", interval = 2000, chance = 10, minDamage = -800, maxDamage = -1400, target = false },
+}
+
+monster.defenses = {
+ defense = 120,
+ armor = 120,
+ mitigation = 3.04,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = -15 },
+ { type = COMBAT_ENERGYDAMAGE, percent = -10 },
+ { type = COMBAT_EARTHDAMAGE, percent = 5 },
+ { type = COMBAT_FIREDAMAGE, percent = 40 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 0 },
+ { type = COMBAT_HOLYDAMAGE, percent = 25 },
+ { type = COMBAT_DEATHDAMAGE, percent = -20 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/darklight_matter.lua b/data-otservbr-global/monster/quests/rotten_blood/darklight_matter.lua
new file mode 100644
index 00000000000..10d4ff36d84
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/darklight_matter.lua
@@ -0,0 +1,127 @@
+local mType = Game.createMonsterType("Darklight Matter")
+local monster = {}
+
+monster.description = "a darklight matter"
+monster.experience = 22250
+monster.outfit = {
+ lookType = 1624,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.raceId = 2380
+monster.Bestiary = {
+ class = "Slime",
+ race = BESTY_RACE_SLIME,
+ toKill = 5000,
+ FirstUnlock = 200,
+ SecondUnlock = 2000,
+ CharmsPoints = 100,
+ Stars = 5,
+ Occurrence = 0,
+ Locations = "Darklight Core.",
+}
+
+monster.health = 30150
+monster.maxHealth = 30150
+monster.race = "venom"
+monster.corpse = 43571
+monster.speed = 230
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 5000,
+ chance = 0,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = false,
+ staticAttackChance = 85,
+ targetDistance = 1,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = false,
+ canWalkOnFire = false,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.voices = {
+ interval = 5000,
+ chance = 10,
+ { text = "*twiggle*", yell = false },
+ { text = "SSSSHRRR...", yell = false },
+}
+
+monster.loot = {
+ { name = "crystal coin", chance = 11755, maxCount = 1 },
+ { name = "unstable darklight matter", chance = 9060, maxCount = 1 },
+ { name = "darklight core", chance = 12887, maxCount = 1 },
+ { name = "ultimate health potion", chance = 6553, maxCount = 6 },
+ { id = 3039, chance = 5852, maxCount = 1 }, -- red gem
+ { name = "darklight matter", chance = 8849, maxCount = 1 },
+ { name = "rubber cap", chance = 7180, maxCount = 1 },
+ { id = 23544, chance = 3500, maxCount = 1 }, -- collar of red plasma
+ { name = "green gem", chance = 3500, maxCount = 1 },
+ { name = "shadow sceptre", chance = 3500, maxCount = 1 },
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1100 },
+ { name = "combat", interval = 2500, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -1400, maxDamage = -1800, radius = 5, effect = CONST_ME_PURPLESMOKE, target = true },
+ { name = "combat", interval = 2500, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -1500, maxDamage = -1600, radius = 5, effect = CONST_ME_GHOSTLY_BITE, target = true },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -1400, maxDamage = -1650, length = 8, spread = 3, effect = CONST_ME_ELECTRICALSPARK, target = false },
+ { name = "largeredring", interval = 2000, chance = 15, minDamage = -800, maxDamage = -1500, target = false },
+}
+
+monster.defenses = {
+ defense = 98,
+ armor = 98,
+ mitigation = 3.28,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = -10 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 40 },
+ { type = COMBAT_EARTHDAMAGE, percent = -10 },
+ { type = COMBAT_FIREDAMAGE, percent = -25 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 20 },
+ { type = COMBAT_HOLYDAMAGE, percent = 0 },
+ { type = COMBAT_DEATHDAMAGE, percent = 0 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = false },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = false },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/darklight_source.lua b/data-otservbr-global/monster/quests/rotten_blood/darklight_source.lua
new file mode 100644
index 00000000000..b6e9c065399
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/darklight_source.lua
@@ -0,0 +1,117 @@
+local mType = Game.createMonsterType("Darklight Source")
+local monster = {}
+
+monster.description = "a darklight source"
+monster.experience = 22465
+monster.outfit = {
+ lookType = 1660,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.raceId = 2398
+monster.Bestiary = {
+ class = "Magical",
+ race = BESTY_RACE_MAGICAL,
+ toKill = 5000,
+ FirstUnlock = 200,
+ SecondUnlock = 2000,
+ CharmsPoints = 100,
+ Stars = 5,
+ Occurrence = 0,
+ Locations = "Darklight Core",
+}
+
+monster.health = 31550
+monster.maxHealth = 31550
+monster.race = "undead"
+monster.corpse = 43840
+monster.speed = 220
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 4000,
+ chance = 10,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 90,
+ targetDistance = 1,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.loot = {
+ { name = "crystal coin", chance = 5214, maxCount = 1 },
+ { name = "yellow darklight matter", chance = 9397, maxCount = 1 },
+ { name = "dark obsidian splinter", chance = 13215, maxCount = 1 },
+ { name = "darklight core", chance = 7570, maxCount = 1 },
+ { name = "small sapphire", chance = 5644, maxCount = 2 },
+ { name = "blue gem", chance = 12909, maxCount = 1 },
+ { name = "twiceslicer", chance = 11596, maxCount = 1 },
+ { name = "white gem", chance = 13964, maxCount = 1 },
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1200 },
+ { name = "combat", interval = 2500, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -1400, maxDamage = -1650, length = 8, spread = 3, effect = CONST_ME_BLUE_ENERGY_SPARK, target = false },
+ { name = "combat", interval = 2500, chance = 20, type = COMBAT_HOLYDAMAGE, minDamage = -1500, maxDamage = -1600, radius = 5, effect = CONST_ME_GHOSTLY_BITE, target = false },
+ { name = "combat", interval = 2500, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -1300, maxDamage = -1500, radius = 5, effect = CONST_ME_ELECTRICALSPARK, target = false },
+}
+
+monster.defenses = {
+ defense = 115,
+ armor = 115,
+ mitigation = 3.19,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = -15 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 55 },
+ { type = COMBAT_EARTHDAMAGE, percent = -10 },
+ { type = COMBAT_FIREDAMAGE, percent = -15 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 40 },
+ { type = COMBAT_HOLYDAMAGE, percent = 0 },
+ { type = COMBAT_DEATHDAMAGE, percent = 0 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/darklight_striker.lua b/data-otservbr-global/monster/quests/rotten_blood/darklight_striker.lua
new file mode 100644
index 00000000000..4d6a19d6dc9
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/darklight_striker.lua
@@ -0,0 +1,120 @@
+local mType = Game.createMonsterType("Darklight Striker")
+local monster = {}
+
+monster.description = "a darklight striker"
+monster.experience = 22200
+monster.outfit = {
+ lookType = 1661,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.raceId = 2399
+monster.Bestiary = {
+ class = "Magical",
+ race = BESTY_RACE_MAGICAL,
+ toKill = 5000,
+ FirstUnlock = 200,
+ SecondUnlock = 2000,
+ CharmsPoints = 100,
+ Stars = 5,
+ Occurrence = 0,
+ Locations = "Darklight Core",
+}
+
+monster.health = 29700
+monster.maxHealth = 29700
+monster.race = "undead"
+monster.corpse = 43844
+monster.speed = 210
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 4000,
+ chance = 10,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 90,
+ targetDistance = 1,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.loot = {
+ { name = "crystal coin", chance = 14380, maxCount = 1 },
+ { name = "unstable darklight matter", chance = 14492, maxCount = 1 },
+ { name = "darklight core", chance = 9783, maxCount = 1 },
+ { name = "small topaz", chance = 11140, maxCount = 3 },
+ { name = "ice rapier", chance = 5104, maxCount = 1 },
+ { name = "dark obsidian splinter", chance = 14185, maxCount = 1 },
+ { name = "blue gem", chance = 7355, maxCount = 1 },
+ { name = "crystal mace", chance = 8812, maxCount = 1 },
+ { name = "zaoan helmet", chance = 5572, maxCount = 1 },
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2500, chance = 100, minDamage = 0, maxDamage = -1100 },
+ { name = "combat", interval = 2500, chance = 15, type = COMBAT_ENERGYDAMAGE, minDamage = -1400, maxDamage = -1650, length = 8, spread = 3, effect = CONST_ME_ELECTRICALSPARK, target = false },
+ { name = "combat", interval = 2500, chance = 15, type = COMBAT_HOLYDAMAGE, minDamage = -1100, maxDamage = -1600, radius = 5, effect = CONST_ME_GHOSTLY_BITE, target = false },
+ { name = "combat", interval = 2500, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -1300, maxDamage = -1500, radius = 5, effect = CONST_ME_ELECTRICALSPARK, target = false },
+ { name = "extended holy chain", interval = 2000, chance = 15, minDamage = -800, maxDamage = -1200 },
+ { name = "largepinkring", interval = 2500, chance = 10, minDamage = -1500, maxDamage = -1900, target = false },
+}
+
+monster.defenses = {
+ defense = 112,
+ armor = 112,
+ mitigation = 3.10,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 10 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 35 },
+ { type = COMBAT_EARTHDAMAGE, percent = -15 },
+ { type = COMBAT_FIREDAMAGE, percent = -25 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 30 },
+ { type = COMBAT_HOLYDAMAGE, percent = 10 },
+ { type = COMBAT_DEATHDAMAGE, percent = 0 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/echo_of_chagorz.lua b/data-otservbr-global/monster/quests/rotten_blood/echo_of_chagorz.lua
new file mode 100644
index 00000000000..3627ffe75be
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/echo_of_chagorz.lua
@@ -0,0 +1,101 @@
+local mType = Game.createMonsterType("Echo Of Chagorz")
+local monster = {}
+
+monster.description = "an echo of Chagorz"
+monster.experience = 0
+monster.outfit = {
+ lookType = 1670,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.health = 90000
+monster.maxHealth = 90000
+monster.race = "undead"
+monster.corpse = 0
+monster.speed = 100
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 2500,
+ chance = 40,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 98,
+ targetDistance = 1,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.voices = {
+ interval = 5000,
+ chance = 10,
+}
+
+monster.loot = {}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = -750, maxDamage = -1750 },
+ { name = "combat", interval = 2700, chance = 37, type = COMBAT_FIREDAMAGE, minDamage = -950, maxDamage = -2000, length = 8, spread = 3, effect = CONST_ME_HITBYFIRE, target = false },
+ { name = "combat", interval = 3300, chance = 37, type = COMBAT_PHYSICALDAMAGE, minDamage = -1100, maxDamage = -1600, length = 8, spread = 0, effect = CONST_ME_EXPLOSIONHIT, target = false },
+}
+
+monster.defenses = {
+ defense = 65,
+ armor = 0,
+ mitigation = 2.0,
+ { name = "combat", interval = 3000, chance = 35, type = COMBAT_HEALING, minDamage = 400, maxDamage = 500, effect = CONST_ME_MAGIC_BLUE, target = false },
+ { name = "speed", interval = 2000, chance = 15, speedChange = 320, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000 },
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 0 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 0 },
+ { type = COMBAT_EARTHDAMAGE, percent = 0 },
+ { type = COMBAT_FIREDAMAGE, percent = 0 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 0 },
+ { type = COMBAT_HOLYDAMAGE, percent = 0 },
+ { type = COMBAT_DEATHDAMAGE, percent = 0 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/echo_of_ichgahal.lua b/data-otservbr-global/monster/quests/rotten_blood/echo_of_ichgahal.lua
new file mode 100644
index 00000000000..f35d2e13997
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/echo_of_ichgahal.lua
@@ -0,0 +1,101 @@
+local mType = Game.createMonsterType("Echo Of Ichgahal")
+local monster = {}
+
+monster.description = "an echo of Ichgahal"
+monster.experience = 0
+monster.outfit = {
+ lookType = 1669,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.health = 90000
+monster.maxHealth = 90000
+monster.race = "undead"
+monster.corpse = 0
+monster.speed = 100
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 2500,
+ chance = 40,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 98,
+ targetDistance = 1,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.voices = {
+ interval = 5000,
+ chance = 10,
+}
+
+monster.loot = {}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = -750, maxDamage = -1750 },
+ { name = "combat", interval = 2700, chance = 37, type = COMBAT_FIREDAMAGE, minDamage = -950, maxDamage = -2000, length = 8, spread = 3, effect = CONST_ME_HITBYFIRE, target = false },
+ { name = "combat", interval = 3300, chance = 37, type = COMBAT_PHYSICALDAMAGE, minDamage = -1100, maxDamage = -1600, length = 8, spread = 0, effect = CONST_ME_EXPLOSIONHIT, target = false },
+}
+
+monster.defenses = {
+ defense = 65,
+ armor = 0,
+ mitigation = 2.0,
+ { name = "combat", interval = 3000, chance = 35, type = COMBAT_HEALING, minDamage = 400, maxDamage = 500, effect = CONST_ME_MAGIC_BLUE, target = false },
+ { name = "speed", interval = 2000, chance = 15, speedChange = 320, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000 },
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 0 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 0 },
+ { type = COMBAT_EARTHDAMAGE, percent = 0 },
+ { type = COMBAT_FIREDAMAGE, percent = 0 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 0 },
+ { type = COMBAT_HOLYDAMAGE, percent = 0 },
+ { type = COMBAT_DEATHDAMAGE, percent = 0 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/echo_of_murcion.lua b/data-otservbr-global/monster/quests/rotten_blood/echo_of_murcion.lua
new file mode 100644
index 00000000000..83a1b002d6b
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/echo_of_murcion.lua
@@ -0,0 +1,101 @@
+local mType = Game.createMonsterType("Echo Of Murcion")
+local monster = {}
+
+monster.description = "an echo of Murcion"
+monster.experience = 0
+monster.outfit = {
+ lookType = 1669,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.health = 90000
+monster.maxHealth = 90000
+monster.race = "undead"
+monster.corpse = 0
+monster.speed = 100
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 2500,
+ chance = 40,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 98,
+ targetDistance = 1,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.voices = {
+ interval = 5000,
+ chance = 10,
+}
+
+monster.loot = {}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = -750, maxDamage = -1750 },
+ { name = "combat", interval = 2700, chance = 37, type = COMBAT_FIREDAMAGE, minDamage = -950, maxDamage = -2000, length = 8, spread = 0, effect = CONST_ME_HITBYFIRE, target = false },
+ { name = "combat", interval = 3300, chance = 37, type = COMBAT_PHYSICALDAMAGE, minDamage = -1100, maxDamage = -1600, length = 8, spread = 0, effect = CONST_ME_EXPLOSIONHIT, target = false },
+}
+
+monster.defenses = {
+ defense = 65,
+ armor = 0,
+ mitigation = 2.0,
+ { name = "combat", interval = 3000, chance = 35, type = COMBAT_HEALING, minDamage = 400, maxDamage = 500, effect = CONST_ME_MAGIC_BLUE, target = false },
+ { name = "speed", interval = 2000, chance = 15, speedChange = 320, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000 },
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 0 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 0 },
+ { type = COMBAT_EARTHDAMAGE, percent = 0 },
+ { type = COMBAT_FIREDAMAGE, percent = 0 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 0 },
+ { type = COMBAT_HOLYDAMAGE, percent = 0 },
+ { type = COMBAT_DEATHDAMAGE, percent = 0 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/echo_of_vemiath.lua b/data-otservbr-global/monster/quests/rotten_blood/echo_of_vemiath.lua
new file mode 100644
index 00000000000..d865ba9ae76
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/echo_of_vemiath.lua
@@ -0,0 +1,101 @@
+local mType = Game.createMonsterType("Echo Of Vemiath")
+local monster = {}
+
+monster.description = "an echo of Vemiath"
+monster.experience = 0
+monster.outfit = {
+ lookType = 1670,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.health = 90000
+monster.maxHealth = 90000
+monster.race = "undead"
+monster.corpse = 0
+monster.speed = 100
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 2500,
+ chance = 40,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 98,
+ targetDistance = 1,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.voices = {
+ interval = 5000,
+ chance = 10,
+}
+
+monster.loot = {}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = -750, maxDamage = -1750 },
+ { name = "combat", interval = 2700, chance = 37, type = COMBAT_FIREDAMAGE, minDamage = -950, maxDamage = -2000, length = 8, spread = 3, effect = CONST_ME_HITBYFIRE, target = false },
+ { name = "combat", interval = 3300, chance = 37, type = COMBAT_PHYSICALDAMAGE, minDamage = -1100, maxDamage = -1600, length = 8, spread = 0, effect = CONST_ME_EXPLOSIONHIT, target = false },
+}
+
+monster.defenses = {
+ defense = 65,
+ armor = 0,
+ mitigation = 2.0,
+ { name = "combat", interval = 3000, chance = 35, type = COMBAT_HEALING, minDamage = 400, maxDamage = 500, effect = CONST_ME_MAGIC_BLUE, target = false },
+ { name = "speed", interval = 2000, chance = 15, speedChange = 320, effect = CONST_ME_MAGIC_RED, target = false, duration = 5000 },
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 0 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 0 },
+ { type = COMBAT_EARTHDAMAGE, percent = 0 },
+ { type = COMBAT_FIREDAMAGE, percent = 0 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 0 },
+ { type = COMBAT_HOLYDAMAGE, percent = 0 },
+ { type = COMBAT_DEATHDAMAGE, percent = 0 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/elder_bloodjaw.lua b/data-otservbr-global/monster/quests/rotten_blood/elder_bloodjaw.lua
new file mode 100644
index 00000000000..37b63816566
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/elder_bloodjaw.lua
@@ -0,0 +1,102 @@
+local mType = Game.createMonsterType("Elder Bloodjaw")
+local monster = {}
+
+monster.description = "an elder bloodjaw"
+monster.experience = 0
+monster.outfit = {
+ lookType = 1628,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.health = 86000
+monster.maxHealth = 86000
+monster.race = "undead"
+monster.corpse = 43669
+monster.speed = 210
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 4000,
+ chance = 10,
+}
+
+monster.strategiesTarget = {
+ nearest = 80,
+ health = 10,
+ damage = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 90,
+ targetDistance = 1,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.voices = {
+ interval = 5000,
+ chance = 10,
+ { text = "SHWAARR!", yell = false },
+ { text = "SHWAARP!", yell = false },
+}
+
+monster.loot = {}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -490 },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -220, maxDamage = -405, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, target = true },
+ { name = "combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -65, maxDamage = -135, radius = 4, effect = CONST_ME_MAGIC_GREEN, target = false },
+ { name = "drunk", interval = 2000, chance = 10, radius = 3, effect = CONST_ME_HITBYPOISON, target = false, duration = 5000 },
+ { name = "blightwalker curse", interval = 2000, chance = 15, target = false },
+ { name = "speed", interval = 2000, chance = 15, speedChange = -300, range = 7, shootEffect = CONST_ANI_POISON, target = true, duration = 30000 },
+}
+
+monster.defenses = {
+ defense = 100,
+ armor = 100,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = -15 },
+ { type = COMBAT_ENERGYDAMAGE, percent = -10 },
+ { type = COMBAT_EARTHDAMAGE, percent = 5 },
+ { type = COMBAT_FIREDAMAGE, percent = 40 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 0 },
+ { type = COMBAT_HOLYDAMAGE, percent = 25 },
+ { type = COMBAT_DEATHDAMAGE, percent = -20 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/meandering_mushroom.lua b/data-otservbr-global/monster/quests/rotten_blood/meandering_mushroom.lua
new file mode 100644
index 00000000000..7dc04b95375
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/meandering_mushroom.lua
@@ -0,0 +1,121 @@
+local mType = Game.createMonsterType("Meandering Mushroom")
+local monster = {}
+
+monster.description = "a meandering mushroom"
+monster.experience = 21980
+monster.outfit = {
+ lookType = 1621,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.raceId = 2376
+monster.Bestiary = {
+ class = "Slime",
+ race = BESTY_RACE_SLIME,
+ toKill = 5000,
+ FirstUnlock = 200,
+ SecondUnlock = 2000,
+ CharmsPoints = 100,
+ Stars = 5,
+ Occurrence = 0,
+ Locations = "Putrefactory.",
+}
+
+monster.health = 29100
+monster.maxHealth = 29100
+monster.race = "undead"
+monster.corpse = 43559
+monster.speed = 205
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 5000,
+ chance = 0,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = false,
+ staticAttackChance = 85,
+ targetDistance = 0,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = false,
+ canWalkOnFire = false,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.loot = {
+ { name = "crystal coin", chance = 11755, maxCount = 1 },
+ { name = "lichen gobbler", chance = 9121, maxCount = 1 },
+ { name = "white mushroom", chance = 12998, maxCount = 3 },
+ { name = "rotten roots", chance = 9791, maxCount = 1 },
+ { name = "wand of decay", chance = 14668, maxCount = 1 },
+ { id = 3039, chance = 10406, maxCount = 1 }, -- red gem
+ { name = "worm sponge", chance = 10697, maxCount = 1 },
+ { name = "dark mushroom", chance = 12313, maxCount = 3 },
+ { name = "yellow gem", chance = 13520, maxCount = 1 },
+ { name = "brown mushroom", chance = 6422, maxCount = 3 },
+ { name = "terra amulet", chance = 13122, maxCount = 1 },
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1150 },
+ { name = "combat", interval = 2500, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -1800, maxDamage = -1900, radius = 5, effect = CONST_ME_MORTAREA, target = true },
+ { name = "combat", interval = 2500, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -1700, maxDamage = -1700, radius = 5, effect = CONST_ME_INSECTS, target = true },
+ { name = "combat", interval = 2500, chance = 20, type = COMBAT_ICEDAMAGE, minDamage = -1100, maxDamage = -1300, length = 8, spread = 5, effect = CONST_ME_BLACKSMOKE, target = false },
+ { name = "largeblackring", interval = 2000, chance = 10, minDamage = -900, maxDamage = -1500, target = false },
+}
+
+monster.defenses = {
+ defense = 115,
+ armor = 115,
+ mitigation = 3.19,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 0 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 25 },
+ { type = COMBAT_EARTHDAMAGE, percent = -20 },
+ { type = COMBAT_FIREDAMAGE, percent = -10 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 40 },
+ { type = COMBAT_HOLYDAMAGE, percent = -15 },
+ { type = COMBAT_DEATHDAMAGE, percent = 50 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = false },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = false },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/mushroom.lua b/data-otservbr-global/monster/quests/rotten_blood/mushroom.lua
new file mode 100644
index 00000000000..d5611b8ea9c
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/mushroom.lua
@@ -0,0 +1,94 @@
+local mType = Game.createMonsterType("Mushroom")
+local monster = {}
+
+monster.description = "a Mushroom"
+monster.experience = 0
+monster.outfit = {
+ lookType = 1669, --todo get correct lookType
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.health = 10000
+monster.maxHealth = 10000
+monster.race = "undead"
+monster.corpse = 0
+monster.speed = 0
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 2500,
+ chance = 40,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 98,
+ targetDistance = 1,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.voices = {}
+
+monster.loot = {}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400 },
+ { name = "combat", interval = 3000, chance = 100, type = COMBAT_LIFEDRAIN, minDamage = -2500, maxDamage = -3000, radius = 3, effect = CONST_ME_POISONAREA, target = false }, -- life drain bomb
+}
+
+monster.defenses = {
+ defense = 65,
+ armor = 0,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 0 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 0 },
+ { type = COMBAT_EARTHDAMAGE, percent = 0 },
+ { type = COMBAT_FIREDAMAGE, percent = 0 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 0 },
+ { type = COMBAT_HOLYDAMAGE, percent = 0 },
+ { type = COMBAT_DEATHDAMAGE, percent = 0 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = true },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = true },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/mycobiontic_beetle.lua b/data-otservbr-global/monster/quests/rotten_blood/mycobiontic_beetle.lua
new file mode 100644
index 00000000000..6a8267c9bc8
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/mycobiontic_beetle.lua
@@ -0,0 +1,129 @@
+local mType = Game.createMonsterType("Mycobiontic Beetle")
+local monster = {}
+
+monster.description = "a mycobiontic beetle"
+monster.experience = 21175
+monster.outfit = {
+ lookType = 1620,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.raceId = 2375
+monster.Bestiary = {
+ class = "Vermin",
+ race = BESTY_RACE_VERMIN,
+ toKill = 5000,
+ FirstUnlock = 200,
+ SecondUnlock = 2000,
+ CharmsPoints = 100,
+ Stars = 5,
+ Occurrence = 0,
+ Locations = "Jaded roots",
+}
+
+monster.health = 30200
+monster.maxHealth = 30200
+monster.race = "undead"
+monster.corpse = 43555
+monster.speed = 230
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 5000,
+ chance = 10,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 90,
+ targetDistance = 0,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.voices = {
+ interval = 5000,
+ chance = 10,
+}
+
+monster.loot = {
+ { name = "crystal coin", chance = 15540 },
+ { name = "ultimate health potion", chance = 43253, maxCount = 5 },
+ { name = "serpent sword", chance = 32253 },
+ { name = "glacier mask", chance = 21920 },
+ { name = "small sapphire", chance = 34560, maxCount = 3 },
+ { name = "organic acid", chance = 11678, maxCount = 1 },
+ { name = "rotten roots", chance = 25920, maxCount = 1 },
+ { name = "scarab coin", chance = 22920, maxCount = 3 },
+ { name = "buckle", chance = 22920, maxCount = 1 },
+ { name = "rotten vermin ichor", chance = 22920, maxCount = 1 },
+ { name = "violet gem", chance = 18920 },
+ { name = "blue gem", chance = 15920 },
+ { name = "small ruby", chance = 24560, maxCount = 3 },
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1600 },
+ { name = "combat", interval = 2500, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -1100, maxDamage = -1400, radius = 5, effect = CONST_ME_GREEN_RINGS, target = true },
+ { name = "combat", intervall = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -1200, maxDamage = -1600, length = 8, spread = 3, effect = CONST_ME_GREEN_RINGS, target = false },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -1400, maxDamage = -1700, radius = 5, effect = CONST_ME_EXPLOSIONAREA, target = false },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -1200, maxDamage = -1400, radius = 5, effect = CONST_ME_GROUNDSHAKER, target = false },
+ { name = "largepoisonring", interval = 2000, chance = 10, minDamage = -900, maxDamage = -1300 },
+}
+
+monster.defenses = {
+ defense = 116,
+ armor = 116,
+ mitigation = 2.92,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 25 },
+ { type = COMBAT_ENERGYDAMAGE, percent = -15 },
+ { type = COMBAT_EARTHDAMAGE, percent = 60 },
+ { type = COMBAT_FIREDAMAGE, percent = 35 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = -25 },
+ { type = COMBAT_HOLYDAMAGE, percent = -5 },
+ { type = COMBAT_DEATHDAMAGE, percent = 0 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = false },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/oozing_carcass.lua b/data-otservbr-global/monster/quests/rotten_blood/oozing_carcass.lua
new file mode 100644
index 00000000000..bc44ba198fb
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/oozing_carcass.lua
@@ -0,0 +1,123 @@
+local mType = Game.createMonsterType("Oozing Carcass")
+local monster = {}
+
+monster.description = "an oozing carcass"
+monster.experience = 20980
+monster.outfit = {
+ lookType = 1626,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.raceId = 2377
+monster.Bestiary = {
+ class = "Undead",
+ race = BESTY_RACE_UNDEAD,
+ toKill = 5000,
+ FirstUnlock = 200,
+ SecondUnlock = 2000,
+ CharmsPoints = 100,
+ Stars = 5,
+ Occurrence = 0,
+ Locations = "Putrefactory.",
+}
+
+monster.health = 27500
+monster.maxHealth = 27500
+monster.race = "undead"
+monster.corpse = 43579
+monster.speed = 215
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 4000,
+ chance = 0,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = false,
+ staticAttackChance = 90,
+ targetDistance = 1,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 4,
+ color = 143,
+}
+
+monster.loot = {
+ { name = "crystal coin", chance = 9000, maxCount = 1 },
+ { name = "lichen gobbler", chance = 12369, maxCount = 1 },
+ { name = "small emerald", chance = 12859, maxCount = 1 },
+ { id = 3039, chance = 9808, maxCount = 1 }, -- red gem
+ { name = "skull staff", chance = 12316, maxCount = 1 },
+ { name = "bone shield", chance = 6752, maxCount = 1 },
+ { name = "yellow gem", chance = 8634, maxCount = 1 },
+ { name = "rotten roots", chance = 13133, maxCount = 1 },
+ { name = "decayed finger bone", chance = 6964, maxCount = 1 },
+ { name = "ultimate health potion", chance = 10285, maxCount = 2 },
+ { name = "bloody edge", chance = 12270, maxCount = 1 },
+ { name = "spellbook of warding", chance = 5084, maxCount = 1 },
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -600 },
+ { name = "combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -1500, maxDamage = -1600, radius = 5, effect = CONST_ME_BLACKSMOKE, target = false },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_ICEDAMAGE, minDamage = -1400, maxDamage = -1500, radius = 5, effect = CONST_ME_ICEAREA, target = false },
+ { name = "combat", interval = 2000, chance = 25, type = COMBAT_ICEDAMAGE, minDamage = -1400, maxDamage = -1550, length = 8, spread = 5, effect = CONST_ME_ICEAREA, target = false },
+ { name = "largedeathring", interval = 2000, chance = 20, minDamage = -850, maxDamage = -1400, target = false },
+ { name = "energy chain", interval = 3000, chance = 20, minDamage = -1050, maxDamage = -1400, target = false },
+}
+
+monster.defenses = {
+ defense = 102,
+ armor = 102,
+ mitigation = 3.10,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 0 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 25 },
+ { type = COMBAT_EARTHDAMAGE, percent = -20 },
+ { type = COMBAT_FIREDAMAGE, percent = -10 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 35 },
+ { type = COMBAT_HOLYDAMAGE, percent = -25 },
+ { type = COMBAT_DEATHDAMAGE, percent = 40 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = true },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/oozing_corpus.lua b/data-otservbr-global/monster/quests/rotten_blood/oozing_corpus.lua
new file mode 100644
index 00000000000..7408ed46ef0
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/oozing_corpus.lua
@@ -0,0 +1,120 @@
+local mType = Game.createMonsterType("Oozing Corpus")
+local monster = {}
+
+monster.description = "an oozing corpus"
+monster.experience = 20600
+monster.outfit = {
+ lookType = 1625,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.raceId = 2381
+monster.Bestiary = {
+ class = "Undead",
+ race = BESTY_RACE_UNDEAD,
+ toKill = 5000,
+ FirstUnlock = 200,
+ SecondUnlock = 2000,
+ CharmsPoints = 100,
+ Stars = 5,
+ Occurrence = 0,
+ Locations = "Jaded Roots.",
+}
+
+monster.health = 28700
+monster.maxHealth = 28700
+monster.race = "undead"
+monster.corpse = 43575
+monster.speed = 220
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 4000,
+ chance = 0,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = false,
+ staticAttackChance = 90,
+ targetDistance = 0,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 4,
+ color = 143,
+}
+
+monster.loot = {
+ { name = "crystal coin", chance = 9000, maxCount = 1 },
+ { name = "organic acid", chance = 7678, maxCount = 1 },
+ { name = "terra boots", chance = 12369, maxCount = 1 },
+ { name = "small amethyst", chance = 12859, maxCount = 1 },
+ { name = "rotten roots", chance = 13133, maxCount = 1 },
+ { name = "blue gem", chance = 9808, maxCount = 1 },
+ { name = "dragonbone staff", chance = 6964, maxCount = 1 },
+ { name = "worm sponge", chance = 7270, maxCount = 1 },
+ { name = "violet gem", chance = 5084, maxCount = 1 },
+ { name = "jade hammer", chance = 3073, maxCount = 1 },
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1600 },
+ { name = "combat", interval = 2500, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -1300, maxDamage = -1700, radius = 5, effect = CONST_ME_GHOSTLY_BITE, target = true },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -1400, maxDamage = -1550, length = 8, spread = 3, effect = CONST_ME_GROUNDSHAKER, target = false },
+ { name = "combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -1100, maxDamage = -1550, length = 8, spread = 3, effect = CONST_ME_GREEN_RINGS, target = false },
+ { name = "death chain", interval = 3000, chance = 15, minDamage = -900, maxDamage = -1300, target = true },
+}
+
+monster.defenses = {
+ defense = 100,
+ armor = 107,
+ mitigation = 3.25,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 30 },
+ { type = COMBAT_ENERGYDAMAGE, percent = -25 },
+ { type = COMBAT_EARTHDAMAGE, percent = 40 },
+ { type = COMBAT_FIREDAMAGE, percent = 25 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = -10 },
+ { type = COMBAT_HOLYDAMAGE, percent = -10 },
+ { type = COMBAT_DEATHDAMAGE, percent = 0 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = true },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/rotten_man-maggot.lua b/data-otservbr-global/monster/quests/rotten_blood/rotten_man-maggot.lua
new file mode 100644
index 00000000000..19eb6d03b27
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/rotten_man-maggot.lua
@@ -0,0 +1,124 @@
+local mType = Game.createMonsterType("Rotten Man-Maggot")
+local monster = {}
+
+monster.description = "a rotten man-maggot"
+monster.experience = 22625
+monster.outfit = {
+ lookType = 1655,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.raceId = 2393
+monster.Bestiary = {
+ class = "Vermin",
+ race = BESTY_RACE_VERMIN,
+ toKill = 5000,
+ FirstUnlock = 200,
+ SecondUnlock = 2000,
+ CharmsPoints = 100,
+ Stars = 5,
+ Occurrence = 0,
+ Locations = "Putrefactory.",
+}
+
+monster.health = 31100
+monster.maxHealth = 31100
+monster.race = "undead"
+monster.corpse = 43820
+monster.speed = 195
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 5000,
+ chance = 10,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = true,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 90,
+ targetDistance = 0,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.voices = {
+ interval = 5000,
+ chance = 10,
+}
+
+monster.loot = {
+ { name = "crystal coin", chance = 10340, maxCount = 1 },
+ { name = "small amethyst", chance = 7364, maxCount = 2 },
+ { name = "lichen gobbler", chance = 8391, maxCount = 1 },
+ { name = "rotten roots", chance = 11619, maxCount = 1 },
+ { id = 6299, chance = 12591, maxCount = 1 }, -- death ring
+ { name = "wood cape", chance = 14371, maxCount = 1 },
+ { id = 3039, chance = 5155, maxCount = 1 }, -- red gem
+ { name = "yellow gem", chance = 9564, maxCount = 1 },
+ { name = "blooded worm", chance = 5096, maxCount = 1 },
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -900 },
+ { name = "combat", interval = 2000, chance = 15, type = COMBAT_DEATHDAMAGE, minDamage = -1100, maxDamage = -1400, radius = 5, effect = CONST_ME_MORTAREA, target = true },
+ { name = "combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -1300, maxDamage = -1800, radius = 5, effect = CONST_ME_GHOSTLY_BITE, target = true },
+ { name = "combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = -1200, maxDamage = -1700, length = 8, spread = 5, effect = CONST_ME_ICEAREA, target = false },
+ { name = "largeicering", interval = 2000, chance = 15, minDamage = -800, maxDamage = -1200, target = false },
+}
+
+monster.defenses = {
+ defense = 110,
+ armor = 110,
+ mitigation = 2.75,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 0 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 55 },
+ { type = COMBAT_EARTHDAMAGE, percent = -15 },
+ { type = COMBAT_FIREDAMAGE, percent = -10 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 40 },
+ { type = COMBAT_HOLYDAMAGE, percent = -15 },
+ { type = COMBAT_DEATHDAMAGE, percent = 30 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = false },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/sopping_carcass.lua b/data-otservbr-global/monster/quests/rotten_blood/sopping_carcass.lua
new file mode 100644
index 00000000000..26458dfe282
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/sopping_carcass.lua
@@ -0,0 +1,110 @@
+local mType = Game.createMonsterType("Sopping Carcass")
+local monster = {}
+
+monster.description = "a sopping carcass"
+monster.experience = 23425
+monster.outfit = {
+ lookType = 1658,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.raceId = 2396
+monster.Bestiary = {
+ class = "Undead",
+ race = BESTY_RACE_UNDEAD,
+ toKill = 5000,
+ FirstUnlock = 200,
+ SecondUnlock = 2000,
+ CharmsPoints = 100,
+ Stars = 5,
+ Occurrence = 0,
+ Locations = "Putrefactory.",
+}
+
+monster.health = 32700
+monster.maxHealth = 32700
+monster.race = "undead"
+monster.corpse = 43832
+monster.speed = 210
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 4000,
+ chance = 0,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = false,
+ staticAttackChance = 90,
+ targetDistance = 0,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.loot = {}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1100 },
+ { name = "combat", interval = 2000, chance = 24, type = COMBAT_DEATHDAMAGE, minDamage = -1400, maxDamage = -1500, radius = 5, effect = CONST_ME_MORTAREA, target = false },
+ { name = "combat", interval = 2500, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -1200, maxDamage = -1400, radius = 5, effect = CONST_ME_GHOSTLY_BITE, target = false },
+ { name = "combat", interval = 2000, chance = 25, type = COMBAT_EARTHDAMAGE, minDamage = -900, maxDamage = -1400, radius = 5, effect = CONST_ME_BIGPLANTS, target = false },
+ { name = "combat", interval = 2000, chance = 25, type = COMBAT_DEATHDAMAGE, minDamage = -1100, maxDamage = -1550, length = 8, spread = 5, effect = CONST_ME_BLACKSMOKE, target = false },
+ { name = "ice chain", interval = 3000, chance = 15, minDamage = -1200, maxDamage = -1500, target = false },
+}
+
+monster.defenses = {
+ defense = 109,
+ armor = 109,
+ mitigation = 3.28,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 0 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 35 },
+ { type = COMBAT_EARTHDAMAGE, percent = -15 },
+ { type = COMBAT_FIREDAMAGE, percent = -5 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 50 },
+ { type = COMBAT_HOLYDAMAGE, percent = -20 },
+ { type = COMBAT_DEATHDAMAGE, percent = 60 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = true },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/sopping_corpus.lua b/data-otservbr-global/monster/quests/rotten_blood/sopping_corpus.lua
new file mode 100644
index 00000000000..24d7a5f87b1
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/sopping_corpus.lua
@@ -0,0 +1,130 @@
+local mType = Game.createMonsterType("Sopping Corpus")
+local monster = {}
+
+monster.description = "a sopping corpus"
+monster.experience = 22465
+monster.outfit = {
+ lookType = 1659,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.raceId = 2397
+monster.Bestiary = {
+ class = "Undead",
+ race = BESTY_RACE_UNDEAD,
+ toKill = 5000,
+ FirstUnlock = 200,
+ SecondUnlock = 2000,
+ CharmsPoints = 100,
+ Stars = 5,
+ Occurrence = 0,
+ Locations = "Jaded Roots.",
+}
+
+monster.health = 33400
+monster.maxHealth = 33400
+monster.race = "undead"
+monster.corpse = 43836
+monster.speed = 210
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 4000,
+ chance = 0,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = false,
+ staticAttackChance = 90,
+ targetDistance = 0,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.voices = {
+ interval = 5000,
+ chance = 10,
+ { text = "*Lessshhh!*", yell = false },
+}
+
+monster.loot = {
+ { name = "crystal coin", chance = 6961, maxCount = 1 },
+ { name = "ultimate mana potion", chance = 10285, maxCount = 2 },
+ { name = "crimson sword", chance = 10090, maxCount = 3 },
+ { name = "ultimate health potion", chance = 10285, maxCount = 2 },
+ { name = "organic acid", chance = 7678, maxCount = 1 },
+ { name = "rotten roots", chance = 13133, maxCount = 1 },
+ { name = "emerald bangle", chance = 8558, maxCount = 1 },
+ { name = "underworld rod", chance = 8380, maxCount = 1 },
+ { name = "violet gem", chance = 5084, maxCount = 1 },
+ { name = "blue gem", chance = 9808, maxCount = 1 },
+ { name = "relic sword", chance = 6964, maxCount = 1 },
+ { name = "skullcracker armor", chance = 7270, maxCount = 1 },
+ { name = "ring of green plasma", chance = 3073, maxCount = 1 },
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1600 },
+ { name = "combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -1300, maxDamage = -1600, length = 8, spread = 3, effect = CONST_ME_GROUNDSHAKER, target = false },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_PHYSICALDAMAGE, minDamage = -1200, maxDamage = -1500, effect = CONST_ME_BIG_SCRATCH, target = true },
+ { name = "combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = -1400, maxDamage = -1600, radius = 5, effect = CONST_ME_GROUNDSHAKER, target = true },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -1200, maxDamage = -1500, length = 8, spread = 3, effect = CONST_ME_GREEN_RINGS, target = false },
+ { name = "largepoisonring", interval = 2000, chance = 10, minDamage = -1000, maxDamage = -1200, target = false },
+}
+
+monster.defenses = {
+ defense = 112,
+ armor = 112,
+ mitigation = 3.25,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 40 },
+ { type = COMBAT_ENERGYDAMAGE, percent = -20 },
+ { type = COMBAT_EARTHDAMAGE, percent = 50 },
+ { type = COMBAT_FIREDAMAGE, percent = 30 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = -10 },
+ { type = COMBAT_HOLYDAMAGE, percent = 5 },
+ { type = COMBAT_DEATHDAMAGE, percent = 10 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = true },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/walking_pillar.lua b/data-otservbr-global/monster/quests/rotten_blood/walking_pillar.lua
new file mode 100644
index 00000000000..89e1e62a109
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/walking_pillar.lua
@@ -0,0 +1,130 @@
+local mType = Game.createMonsterType("Walking Pillar")
+local monster = {}
+
+monster.description = "a walking pillar"
+monster.experience = 24300
+monster.outfit = {
+ lookType = 1656,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.raceId = 2394
+monster.Bestiary = {
+ class = "Construct",
+ race = BESTY_RACE_CONSTRUCT,
+ toKill = 5000,
+ FirstUnlock = 200,
+ SecondUnlock = 2000,
+ CharmsPoints = 100,
+ Stars = 5,
+ Occurrence = 0,
+ Locations = "Darklight Core",
+}
+
+monster.health = 38000
+monster.maxHealth = 38000
+monster.race = "undead"
+monster.corpse = 43824
+monster.speed = 190
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 4000,
+ chance = 10,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = true,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 90,
+ targetDistance = 1,
+ runHealth = 50,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = false,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.voices = {
+ interval = 5000,
+ chance = 10,
+ { text = "TREEMBLE", yell = false },
+}
+
+monster.loot = {
+ { name = "crystal coin", chance = 12186, maxCount = 1 },
+ { name = "yellow darklight matter", chance = 5354, maxCount = 1 },
+ { name = "magma clump", chance = 11440, maxCount = 1 },
+ { name = "darklight core", chance = 10276, maxCount = 1 },
+ { id = 12600, chance = 8489, maxCount = 4 }, -- coal
+ { name = "darklight basalt chunk", chance = 12855, maxCount = 1 },
+ { name = "onyx chip", chance = 12831, maxCount = 2 },
+ { name = "strange helmet", chance = 11001, maxCount = 1 },
+ { name = "fire sword", chance = 8347, maxCount = 1 },
+ { name = "ultimate mana potion", chance = 9687, maxCount = 3 },
+ { name = "blue gem", chance = 5868, maxCount = 1 },
+ { name = "magma legs", chance = 14497, maxCount = 1 },
+ { name = "white gem", chance = 9936, maxCount = 1 },
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1500 },
+ { name = "combat", interval = 2000, chance = 10, type = COMBAT_ENERGYDAMAGE, minDamage = -1400, maxDamage = -1650, length = 8, spread = 3, effect = CONST_ME_BLUE_ENERGY_SPARK, target = false },
+ { name = "combat", intervall = 2000, chance = 20, type = COMBAT_HOLYDAMAGE, minDamage = -1500, maxDamage = -1800, radius = 5, effect = CONST_ME_PURPLESMOKE, target = true },
+ { name = "combat", interval = 2000, chance = 10, type = COMBAT_HOLYDAMAGE, minDamage = -1200, maxDamage = -1200, radius = 5, effect = CONST_ME_GHOSTLY_BITE, target = true },
+ { name = "extended energy chain", interval = 2000, chance = 5, minDamage = -800, maxDamage = 1200, target = true },
+ { name = "largepinkring", interval = 3500, chance = 10, minDamage = -1100, maxDamage = -1600, target = false },
+}
+
+monster.defenses = {
+ defense = 120,
+ armor = 120,
+ mitigation = 2.75,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = -10 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 60 },
+ { type = COMBAT_EARTHDAMAGE, percent = -15 },
+ { type = COMBAT_FIREDAMAGE, percent = -15 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 45 },
+ { type = COMBAT_HOLYDAMAGE, percent = 0 },
+ { type = COMBAT_DEATHDAMAGE, percent = 10 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/monster/quests/rotten_blood/wandering_pillar.lua b/data-otservbr-global/monster/quests/rotten_blood/wandering_pillar.lua
new file mode 100644
index 00000000000..e6cfb42a355
--- /dev/null
+++ b/data-otservbr-global/monster/quests/rotten_blood/wandering_pillar.lua
@@ -0,0 +1,133 @@
+local mType = Game.createMonsterType("Wandering Pillar")
+local monster = {}
+
+monster.description = "a wandering pillar"
+monster.experience = 23200
+monster.outfit = {
+ lookType = 1657,
+ lookHead = 0,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 0,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.raceId = 2395
+monster.Bestiary = {
+ class = "Construct",
+ race = BESTY_RACE_CONSTRUCT,
+ toKill = 5000,
+ FirstUnlock = 200,
+ SecondUnlock = 2000,
+ CharmsPoints = 100,
+ Stars = 5,
+ Occurrence = 0,
+ Locations = "Darklight Core",
+}
+
+monster.health = 37000
+monster.maxHealth = 37000
+monster.race = "undead"
+monster.corpse = 43828
+monster.speed = 190
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 4000,
+ chance = 10,
+}
+
+monster.strategiesTarget = {
+ nearest = 70,
+ health = 10,
+ damage = 10,
+ random = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = false,
+ illusionable = true,
+ canPushItems = true,
+ canPushCreatures = true,
+ staticAttackChance = 90,
+ targetDistance = 1,
+ runHealth = 50,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = false,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.voices = {
+ interval = 5000,
+ chance = 10,
+ { text = "POWERRR!!", yell = false },
+ { text = "DARKNESS. DEATH. ENERGIES.", yell = false },
+ { text = "TREMMMBLE!", yell = false },
+}
+
+monster.loot = {
+ { name = "crystal coin", chance = 6629, maxCount = 1 },
+ { name = "darklight obsidian axe", chance = 14652, maxCount = 1 },
+ { name = "basalt crumbs", chance = 8184, maxCount = 1 },
+ { name = "sulphurous stone", chance = 5873, maxCount = 1 },
+ { name = "magma boots", chance = 5080, maxCount = 1 },
+ { id = 12600, chance = 9802, maxCount = 4 }, -- coal
+ { name = "dark helmet", chance = 7490, maxCount = 1 },
+ { name = "magma coat", chance = 11753, maxCount = 1 },
+ { name = "onyx chip", chance = 9311, maxCount = 2 },
+ { name = "darklight core", chance = 5957, maxCount = 1 },
+ { name = "fire sword", chance = 8319, maxCount = 1 },
+ { name = "magma clump", chance = 6260, maxCount = 1 },
+ { id = 3039, chance = 9915, maxCount = 1 }, -- red gem
+ { name = "green gem", chance = 12864, maxCount = 1 },
+ { name = "basalt core", chance = 9037, maxCount = 1 },
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -1200 },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -1400, maxDamage = -1650, length = 8, spread = 3, effect = CONST_ME_BLUE_ENERGY_SPARK, target = false },
+ { name = "combat", intervall = 2000, chance = 20, type = COMBAT_ENERGYDAMAGE, minDamage = -1100, maxDamage = -1500, radius = 5, effect = CONST_ME_PINK_BEAM, target = false },
+ { name = "combat", interval = 2000, chance = 20, type = COMBAT_FIREDAMAGE, minDamage = -1400, maxDamage = -1700, radius = 5, effect = CONST_ME_HITBYFIRE, target = true },
+ { name = "largeholyring", interval = 3000, chance = 15, minDamage = -900, maxDamage = -1250 },
+}
+
+monster.defenses = {
+ defense = 120,
+ armor = 120,
+ mitigation = 2.75,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = -10 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 60 },
+ { type = COMBAT_EARTHDAMAGE, percent = -15 },
+ { type = COMBAT_FIREDAMAGE, percent = -15 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 45 },
+ { type = COMBAT_HOLYDAMAGE, percent = 0 },
+ { type = COMBAT_DEATHDAMAGE, percent = 10 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType:register(monster)
diff --git a/data-otservbr-global/npc/bloodshade_rotten.lua b/data-otservbr-global/npc/bloodshade_rotten.lua
new file mode 100644
index 00000000000..5d46776a40d
--- /dev/null
+++ b/data-otservbr-global/npc/bloodshade_rotten.lua
@@ -0,0 +1,79 @@
+local npcType = Game.createNpcType("Bloodshade Rotten")
+local npcConfig = {}
+
+local npcName = "A Bloodshade"
+npcConfig.name = npcName
+npcConfig.description = npcName
+
+npcConfig.health = 100
+npcConfig.maxHealth = npcConfig.health
+npcConfig.walkInterval = 0
+npcConfig.walkRadius = 0
+
+npcConfig.outfit = {
+ lookType = 1414,
+}
+
+npcConfig.flags = {
+ floorchange = false,
+}
+
+local keywordHandler = KeywordHandler:new()
+local npcHandler = NpcHandler:new(keywordHandler)
+
+npcType.onThink = function(npc, interval)
+ npcHandler:onThink(npc, interval)
+end
+
+npcType.onAppear = function(npc, creature)
+ npcHandler:onAppear(npc, creature)
+end
+
+npcType.onDisappear = function(npc, creature)
+ npcHandler:onDisappear(npc, creature)
+end
+
+npcType.onMove = function(npc, creature, fromPosition, toPosition)
+ npcHandler:onMove(npc, creature, fromPosition, toPosition)
+end
+
+npcType.onSay = function(npc, creature, type, message)
+ npcHandler:onSay(npc, creature, type, message)
+end
+
+local function creatureSayCallback(npc, creature, type, message)
+ local player = Player(creature)
+ local playerId = player:getId()
+
+ if not npcHandler:checkInteraction(npc, creature) then
+ return false
+ end
+
+ local access = player:kv():scoped("rotten-blood-quest"):get("access") or 0
+ if access == 5 then
+ npcHandler:say("You already have started this quest.", npc, creature)
+ npcHandler:setTopic(playerId, 0)
+ return true
+ end
+
+ message = message:lower()
+ if MsgContains(message, "quest") then
+ npcHandler:say({
+ "First you must fight the two pairs of evil twins that lurk in the realm beyond here. ...",
+ "Only when you are victorious over all four of them, your path to the source of vileness, the path to Bakragore will be opened. ...",
+ "And even this victory will only be the beginning.",
+ }, npc, creature)
+ player:kv():scoped("rotten-blood-quest"):set("access", 5)
+ end
+
+ return true
+end
+
+npcHandler:setMessage(MESSAGE_GREET, "Mortal! If you are on a {quest} to serve the blood god, my master - be greeted!")
+npcHandler:setMessage(MESSAGE_WALKAWAY, "Bye.")
+npcHandler:setMessage(MESSAGE_FAREWELL, "Bye, |PLAYERNAME|.")
+
+npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
+npcHandler:addModule(FocusModule:new(), npcConfig.name, true, true, true)
+
+npcType:register(npcConfig)
diff --git a/data-otservbr-global/npc/bloodshade_sacrifice.lua b/data-otservbr-global/npc/bloodshade_sacrifice.lua
new file mode 100644
index 00000000000..37e1cf0fe7b
--- /dev/null
+++ b/data-otservbr-global/npc/bloodshade_sacrifice.lua
@@ -0,0 +1,100 @@
+local npcType = Game.createNpcType("Bloodshade Sacrifice")
+local npcConfig = {}
+
+local npcName = "A Bloodshade"
+npcConfig.name = npcName
+npcConfig.description = npcName
+
+npcConfig.health = 100
+npcConfig.maxHealth = npcConfig.health
+npcConfig.walkInterval = 0
+npcConfig.walkRadius = 0
+
+npcConfig.outfit = {
+ lookType = 1414,
+}
+
+npcConfig.flags = {
+ floorchange = false,
+}
+
+local keywordHandler = KeywordHandler:new()
+local npcHandler = NpcHandler:new(keywordHandler)
+
+npcType.onThink = function(npc, interval)
+ npcHandler:onThink(npc, interval)
+end
+
+npcType.onAppear = function(npc, creature)
+ npcHandler:onAppear(npc, creature)
+end
+
+npcType.onDisappear = function(npc, creature)
+ npcHandler:onDisappear(npc, creature)
+end
+
+npcType.onMove = function(npc, creature, fromPosition, toPosition)
+ npcHandler:onMove(npc, creature, fromPosition, toPosition)
+end
+
+npcType.onSay = function(npc, creature, type, message)
+ npcHandler:onSay(npc, creature, type, message)
+end
+
+local function creatureSayCallback(npc, creature, type, message)
+ local player = Player(creature)
+ local playerId = player:getId()
+
+ if not npcHandler:checkInteraction(npc, creature) then
+ return false
+ end
+
+ local access = player:kv():scoped("rotten-blood-quest"):get("access") or 0
+ if access > 2 then
+ npcHandler:say("You already have access.", npc, creature)
+ npcHandler:setTopic(playerId, 0)
+ return true
+ end
+
+ message = message:lower()
+ if MsgContains(message, "quest") then
+ npcHandler:say({
+ "To enter the realm of the sanguine master and destroy its spawn, a sufficient sacrifice is imperative. ...",
+ "Find and slay the keeper of blooded tears and bring the nectar of his eyes before the blood god. Present your gift on the sacrificial altar. ...",
+ "After - and under no circumstances before - you have completed this procedure, you can enter the sacred fluid. You can, of course also take a slightly faster... {detour}.",
+ }, npc, creature)
+ npcHandler:setTopic(playerId, 1)
+ elseif MsgContains(message, "detour") and npcHandler:getTopic(playerId) == 1 then
+ npcHandler:say({
+ "Hm. I see. Well, I will be frank. Every blood sacrifice has its price. Blood money will please the blood god... just as well. ...",
+ "The sum would be five million gold pieces and I... my master will be pleased. Are you prepared for a sacrifice such as this?",
+ }, npc, creature)
+ npcHandler:setTopic(playerId, 2)
+ elseif MsgContains(message, "yes") and npcHandler:getTopic(playerId) == 2 then
+ npcHandler:say("You are willing to pay 5000000 gold pieces, then? There is no turning back after our... transaction is complete. Are you sure?", npc, creature)
+ npcHandler:setTopic(playerId, 3)
+ elseif MsgContains(message, "yes") and npcHandler:getTopic(playerId) == 3 then
+ if not player:removeMoneyBank(5000000) then
+ npcHandler:say("Sorry, you don't have enough gold.", npc, creature)
+ npcHandler:setTopic(playerId, 0)
+ return true
+ end
+ npcHandler:say("The bargain has been made, the business is done.", npc, creature)
+ npcHandler:setTopic(playerId, 0)
+ player:kv():scoped("rotten-blood-quest"):set("access", 4)
+ elseif MsgContains(message, "no") and npcHandler:getTopic(playerId) == 1 then
+ npcHandler:setTopic(playerId, 0)
+ npcHandler:say("Ok then not.", npc, creature)
+ end
+
+ return true
+end
+
+npcHandler:setMessage(MESSAGE_GREET, "Mortal! If you are on a {quest} to serve the blood god, my master - be greeted!")
+npcHandler:setMessage(MESSAGE_WALKAWAY, "Bye.")
+npcHandler:setMessage(MESSAGE_FAREWELL, "Bye, |PLAYERNAME|.")
+
+npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
+npcHandler:addModule(FocusModule:new(), npcConfig.name, true, true, true)
+
+npcType:register(npcConfig)
diff --git a/data-otservbr-global/npc/torkada.lua b/data-otservbr-global/npc/torkada.lua
new file mode 100644
index 00000000000..ddbe4d0326e
--- /dev/null
+++ b/data-otservbr-global/npc/torkada.lua
@@ -0,0 +1,103 @@
+local internalNpcName = "Torkada"
+local npcType = Game.createNpcType(internalNpcName)
+local npcConfig = {}
+
+npcConfig.name = internalNpcName
+npcConfig.description = internalNpcName
+
+npcConfig.health = 100
+npcConfig.maxHealth = npcConfig.health
+npcConfig.walkInterval = 0
+npcConfig.walkRadius = 0
+
+npcConfig.outfit = {
+ lookType = 1243,
+ lookHead = 59,
+ lookBody = 78,
+ lookLegs = 78,
+ lookFeet = 57,
+ lookAddons = 0,
+}
+
+npcConfig.flags = {
+ floorchange = false,
+}
+
+local keywordHandler = KeywordHandler:new()
+local npcHandler = NpcHandler:new(keywordHandler)
+
+npcType.onThink = function(npc, interval)
+ npcHandler:onThink(npc, interval)
+end
+
+npcType.onAppear = function(npc, creature)
+ npcHandler:onAppear(npc, creature)
+end
+
+npcType.onDisappear = function(npc, creature)
+ npcHandler:onDisappear(npc, creature)
+end
+
+npcType.onMove = function(npc, creature, fromPosition, toPosition)
+ npcHandler:onMove(npc, creature, fromPosition, toPosition)
+end
+
+npcType.onSay = function(npc, creature, type, message)
+ npcHandler:onSay(npc, creature, type, message)
+end
+
+local function creatureSayCallback(npc, creature, type, message)
+ local player = Player(creature)
+ local playerId = player:getId()
+
+ if not npcHandler:checkInteraction(npc, creature) then
+ return false
+ end
+
+ if player:getLevel() < 250 then
+ npcHandler:say("You need at least level 250 to start our mission.", npc, creature)
+ return false
+ end
+
+ local access = player:kv():scoped("rotten-blood-quest"):get("access") or 0
+ if access > 0 then
+ if player:getStorageValue(Storage.Quest.U13_20.RottenBlood.AccessDoor) ~= 1 then
+ player:setStorageValue(Storage.Quest.U13_20.RottenBlood.AccessDoor, 1)
+ end
+ npcHandler:say("You already have accepted this mission.", npc, creature)
+ npcHandler:setTopic(playerId, 0)
+ return true
+ end
+
+ message = message:lower()
+ if MsgContains(message, "time") then
+ npcHandler:say("This expedition is here on an important {mission} for the inquisition", npc, creature)
+ npcHandler:setTopic(playerId, 1)
+ elseif MsgContains(message, "mission") and npcHandler:getTopic(playerId) == 1 then
+ npcHandler:say("Are you willing, to bring the fury of the inquisition to that foul place and eradicate all evil you find? Speak, {yes} or {no}?", npc, creature)
+ npcHandler:setTopic(playerId, 2)
+ elseif MsgContains(message, "yes") and npcHandler:getTopic(playerId) == 2 then
+ npcHandler:setTopic(playerId, 0)
+ npcHandler:say({
+ "So hereby receive the blessings of the gods, provided by me as the voice of the inquisition! ...",
+ "Go now and search the ancient temple in the north-west part of the drefian ruins. Slay the evil that lurks there and cleanse the foul place from its taint!",
+ }, npc, creature)
+ player:kv():scoped("rotten-blood-quest"):set("access", 1)
+ player:setStorageValue(Storage.Quest.U13_20.RottenBlood.AccessDoor, 1)
+ player:getPosition():sendMagicEffect(CONST_ME_HOLYAREA)
+ elseif MsgContains(message, "no") and npcHandler:getTopic(playerId) == 1 then
+ npcHandler:setTopic(playerId, 0)
+ npcHandler:say("Ok then not.", npc, creature)
+ end
+
+ return true
+end
+
+npcHandler:setMessage(MESSAGE_GREET, "Greetings! This isn't the {time} to chitchat though.")
+npcHandler:setMessage(MESSAGE_WALKAWAY, "Bye.")
+npcHandler:setMessage(MESSAGE_FAREWELL, "Bye, |PLAYERNAME|.")
+
+npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
+npcHandler:addModule(FocusModule:new(), npcConfig.name, true, true, true)
+
+npcType:register(npcConfig)
diff --git a/data-otservbr-global/scripts/actions/bosses_levers/rotten_bakragore.lua b/data-otservbr-global/scripts/actions/bosses_levers/rotten_bakragore.lua
new file mode 100644
index 00000000000..09cf6f78378
--- /dev/null
+++ b/data-otservbr-global/scripts/actions/bosses_levers/rotten_bakragore.lua
@@ -0,0 +1,24 @@
+local config = {
+ boss = {
+ name = "Bakragore",
+ position = Position(33044, 32394, 15),
+ },
+ requiredLevel = 250,
+ timeToFightAgain = ParseDuration("68h") / ParseDuration("1s"),
+ playerPositions = {
+ { pos = Position(33078, 32398, 15), teleport = Position(33044, 32407, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(33077, 32398, 15), teleport = Position(33044, 32407, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(33076, 32398, 15), teleport = Position(33044, 32407, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(33075, 32398, 15), teleport = Position(33044, 32407, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(33074, 32398, 15), teleport = Position(33044, 32407, 15), effect = CONST_ME_TELEPORT },
+ },
+ specPos = {
+ from = Position(33034, 32389, 15),
+ to = Position(33053, 32410, 15),
+ },
+ exit = Position(33044, 32409, 15),
+}
+
+local lever = BossLever(config)
+lever:position(Position(33079, 32398, 15))
+lever:register()
diff --git a/data-otservbr-global/scripts/actions/bosses_levers/rotten_chagorz.lua b/data-otservbr-global/scripts/actions/bosses_levers/rotten_chagorz.lua
new file mode 100644
index 00000000000..2e21f18f3ac
--- /dev/null
+++ b/data-otservbr-global/scripts/actions/bosses_levers/rotten_chagorz.lua
@@ -0,0 +1,23 @@
+local config = {
+ boss = {
+ name = "Chagorz",
+ position = Position(33044, 32361, 15),
+ },
+ requiredLevel = 250,
+ playerPositions = {
+ { pos = Position(33078, 32367, 15), teleport = Position(33044, 32373, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(33077, 32367, 15), teleport = Position(33044, 32373, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(33076, 32367, 15), teleport = Position(33044, 32373, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(33075, 32367, 15), teleport = Position(33044, 32373, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(33074, 32367, 15), teleport = Position(33044, 32373, 15), effect = CONST_ME_TELEPORT },
+ },
+ specPos = {
+ from = Position(33035, 32327, 15),
+ to = Position(33053, 32345, 15),
+ },
+ exit = Position(33043, 32344, 15),
+}
+
+local lever = BossLever(config)
+lever:position(Position(33079, 32367, 15))
+lever:register()
diff --git a/data-otservbr-global/scripts/actions/bosses_levers/rotten_ichgahal.lua b/data-otservbr-global/scripts/actions/bosses_levers/rotten_ichgahal.lua
new file mode 100644
index 00000000000..32f44d9acc5
--- /dev/null
+++ b/data-otservbr-global/scripts/actions/bosses_levers/rotten_ichgahal.lua
@@ -0,0 +1,23 @@
+local config = {
+ boss = {
+ name = "Ichgahal",
+ position = Position(33008, 32333, 15),
+ },
+ requiredLevel = 250,
+ playerPositions = {
+ { pos = Position(32978, 32333, 15), teleport = Position(33004, 32341, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(32977, 32333, 15), teleport = Position(33004, 32341, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(32976, 32333, 15), teleport = Position(33004, 32341, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(32975, 32333, 15), teleport = Position(33004, 32341, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(32974, 32333, 15), teleport = Position(33004, 32341, 15), effect = CONST_ME_TELEPORT },
+ },
+ specPos = {
+ from = Position(32998, 32326, 15),
+ to = Position(33018, 32343, 15),
+ },
+ exit = Position(33004, 32343, 15),
+}
+
+local lever = BossLever(config)
+lever:position(Position(32979, 32333, 15))
+lever:register()
diff --git a/data-otservbr-global/scripts/actions/bosses_levers/rotten_murcion.lua b/data-otservbr-global/scripts/actions/bosses_levers/rotten_murcion.lua
new file mode 100644
index 00000000000..0c163f8db3d
--- /dev/null
+++ b/data-otservbr-global/scripts/actions/bosses_levers/rotten_murcion.lua
@@ -0,0 +1,23 @@
+local config = {
+ boss = {
+ name = "Murcion",
+ position = Position(33009, 32362, 15),
+ },
+ requiredLevel = 250,
+ playerPositions = {
+ { pos = Position(32978, 32365, 15), teleport = Position(33009, 32371, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(32977, 32365, 15), teleport = Position(33009, 32371, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(32976, 32365, 15), teleport = Position(33009, 32371, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(32975, 32365, 15), teleport = Position(33009, 32371, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(32974, 32365, 15), teleport = Position(33009, 32371, 15), effect = CONST_ME_TELEPORT },
+ },
+ specPos = {
+ from = Position(32999, 32359, 15),
+ to = Position(33019, 32376, 15),
+ },
+ exit = Position(33009, 32374, 15),
+}
+
+local lever = BossLever(config)
+lever:position(Position(32979, 32365, 15))
+lever:register()
diff --git a/data-otservbr-global/scripts/actions/bosses_levers/rotten_vemiath.lua b/data-otservbr-global/scripts/actions/bosses_levers/rotten_vemiath.lua
new file mode 100644
index 00000000000..a018c622eff
--- /dev/null
+++ b/data-otservbr-global/scripts/actions/bosses_levers/rotten_vemiath.lua
@@ -0,0 +1,23 @@
+local config = {
+ boss = {
+ name = "Vemiath",
+ position = Position(33044, 32332, 15),
+ },
+ requiredLevel = 250,
+ playerPositions = {
+ { pos = Position(33078, 32333, 15), teleport = Position(33043, 32341, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(33077, 32333, 15), teleport = Position(33043, 32341, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(33076, 32333, 15), teleport = Position(33043, 32341, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(33075, 32333, 15), teleport = Position(33043, 32341, 15), effect = CONST_ME_TELEPORT },
+ { pos = Position(33074, 32333, 15), teleport = Position(33043, 32341, 15), effect = CONST_ME_TELEPORT },
+ },
+ specPos = {
+ from = Position(33034, 32357, 15),
+ to = Position(33052, 32376, 15),
+ },
+ exit = Position(33043, 32344, 15),
+}
+
+local lever = BossLever(config)
+lever:position(Position(33079, 32333, 15))
+lever:register()
diff --git a/data-otservbr-global/scripts/actions/quests/rotten_blood/blood_entrance.lua b/data-otservbr-global/scripts/actions/quests/rotten_blood/blood_entrance.lua
new file mode 100644
index 00000000000..4830adfa615
--- /dev/null
+++ b/data-otservbr-global/scripts/actions/quests/rotten_blood/blood_entrance.lua
@@ -0,0 +1,61 @@
+local config = {
+ entrance = Position(32953, 32398, 9),
+ noAccess = Position(32955, 32398, 9),
+ destination = Position(34070, 31975, 14),
+}
+
+local function getDamage(currentHealth)
+ local damage = math.max(math.floor(currentHealth * 0.20), 1)
+ local newHealth = currentHealth - damage
+ return newHealth > 10 and damage or 0
+end
+
+local accessBlood = MoveEvent()
+function accessBlood.onStepIn(creature, item, position, fromPosition)
+ local player = creature:getPlayer()
+ if not player then
+ return false
+ end
+
+ if player:getLevel() < 250 then
+ player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need at least level 250 to enter.")
+ player:teleportTo(fromPosition, true)
+ return false
+ end
+
+ local access = player:kv():scoped("rotten-blood-quest"):get("access") or 0
+ if access < 4 then
+ player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You offerings to this sanguine master of this realm have been insufficient. You can not pass.")
+ player:teleportTo(config.noAccess, true)
+ player:addHealth(-getDamage(player:getHealth()), COMBAT_PHYSICALDAMAGE)
+ return false
+ end
+
+ if config.entrance == position then
+ player:teleportTo(config.destination)
+ player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
+ end
+
+ return true
+end
+
+accessBlood:type("stepin")
+accessBlood:position(config.entrance)
+accessBlood:register()
+
+----------- Leave from Rotten -----------
+local leaveBlood = MoveEvent()
+function leaveBlood.onStepIn(creature, item, position, fromPosition)
+ local player = creature:getPlayer()
+ if not player then
+ return false
+ end
+
+ player:teleportTo(Position(32955, 32398, 9))
+ player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
+ return true
+end
+
+leaveBlood:type("stepin")
+leaveBlood:position(Position(34070, 31974, 14))
+leaveBlood:register()
diff --git a/data-otservbr-global/scripts/actions/quests/rotten_blood/bosses_killed.lua b/data-otservbr-global/scripts/actions/quests/rotten_blood/bosses_killed.lua
new file mode 100644
index 00000000000..2bb1fa3d53c
--- /dev/null
+++ b/data-otservbr-global/scripts/actions/quests/rotten_blood/bosses_killed.lua
@@ -0,0 +1,50 @@
+local bossesRottenBlood = CreatureEvent("RottenBloodBossDeath")
+function bossesRottenBlood.onDeath(creature)
+ local bossName = creature:getName():lower()
+ if not table.contains({ "murcion", "chagorz", "ichgahal", "vemiath" }, bossName) then
+ return false
+ end
+
+ onDeathForDamagingPlayers(creature, function(creature, player)
+ local now = os.time()
+ local kv = player:kv():scoped("rotten-blood-quest")
+ local cooldown = kv:scoped(bossName):get("cooldown") or 0
+ if cooldown <= now then
+ kv:scoped(bossName):set("cooldown", now + 20 * 60 * 60)
+ kv:set("taints", math.min(((kv:get("taints") or 0) + 1), 4))
+ logger.info("taints: {}", kv:get("taints"))
+ end
+ end)
+
+ return true
+end
+
+bossesRottenBlood:register()
+
+-------------- Bakragore OnDeath --------------
+local bakragoreOnDeath = CreatureEvent("RottenBloodBakragoreDeath")
+function bakragoreOnDeath.onDeath(creature)
+ local bossName = creature:getName():lower()
+ if bossName ~= "bakragore" then
+ return false
+ end
+
+ onDeathForDamagingPlayers(creature, function(creature, player)
+ local kv = player:kv():scoped("rotten-blood-quest")
+ local checkBoss = kv:get(bossName) or false
+ if not checkBoss then
+ kv:set(bossName, true)
+ if not player:hasOutfit("1663") or not player:hasOutfit("1662") then
+ player:addOutfitAddon("1663", 1)
+ player:addOutfitAddon("1662", 1)
+ player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Congratulations! You have won a Decaying Defender Outfit.")
+ end
+ end
+ kv:set("taints", 0)
+ logger.info("taints after: {}", kv:get("taints"))
+ end)
+
+ return true
+end
+
+bakragoreOnDeath:register()
diff --git a/data-otservbr-global/scripts/actions/quests/rotten_blood/entrances.lua b/data-otservbr-global/scripts/actions/quests/rotten_blood/entrances.lua
new file mode 100644
index 00000000000..8434c3fdd8f
--- /dev/null
+++ b/data-otservbr-global/scripts/actions/quests/rotten_blood/entrances.lua
@@ -0,0 +1,104 @@
+local entrances = {
+ { position = Position(34092, 31978, 14), destination = Position(33842, 31651, 13) }, -- Murcion hunt area
+ { position = Position(33842, 31650, 13), destination = Position(34092, 31979, 14) }, -- leave Murcion hunt area
+ { position = Position(33905, 31693, 15), destination = Position(32971, 32368, 15) }, -- Murcion lever room
+
+ { position = Position(34093, 32009, 14), destination = Position(33809, 31815, 13) }, -- Chagorz hunt area
+ { position = Position(33809, 31814, 13), destination = Position(34092, 32009, 14) }, -- leave Chagorz hunt area
+ { position = Position(33902, 31881, 15), destination = Position(33071, 32370, 15) }, -- Chagorz lever room
+
+ { position = Position(34120, 31978, 14), destination = Position(34101, 31678, 13) }, -- Ichgahal hunt area
+ { position = Position(34101, 31677, 13), destination = Position(34119, 31979, 14) }, -- leave Ichgahal hunt area
+ { position = Position(34065, 31716, 15), destination = Position(32971, 32336, 15) }, -- Ichgahal lever room
+
+ { position = Position(34117, 32010, 15), destination = Position(34119, 31876, 14) }, -- Vemiath hunt area
+ { position = Position(34119, 31875, 14), destination = Position(34118, 32010, 15) }, -- leave Vemiath hunt area
+ { position = Position(34002, 31820, 15), destination = Position(33071, 32336, 15) }, -- Vemiath lever room
+
+ { position = Position(33069, 32405, 15), destination = Position(34106, 32052, 13) }, -- Bakragore leave room
+}
+
+local teleportEvent = MoveEvent()
+
+function teleportEvent.onStepIn(creature, item, position, fromPosition)
+ local player = creature:getPlayer()
+ if not player then
+ return false
+ end
+
+ local access = player:kv():scoped("rotten-blood-quest"):get("access") or 0
+ if access < 5 then
+ player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You should pay respect to the Bloodshade guarding this realm before entering.")
+ player:teleportTo(fromPosition, true)
+ return false
+ end
+
+ for _, entrance in pairs(entrances) do
+ if entrance.position == position then
+ player:teleportTo(entrance.destination)
+ player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
+ break
+ end
+ end
+
+ return true
+end
+
+teleportEvent:type("stepin")
+for _, entrance in pairs(entrances) do
+ teleportEvent:position(entrance.position)
+end
+teleportEvent:register()
+
+----------- Bakragore Entrance Check -----------
+local entrance = {
+ position = Position(34106, 32054, 13),
+ destination = Position(33071, 32403, 15), -- Bakragore lever room
+}
+
+local bakragoreEntrance = MoveEvent()
+
+function bakragoreEntrance.onStepIn(creature, item, position, fromPosition)
+ local player = creature:getPlayer()
+ if not player then
+ return false
+ end
+
+ if player:getLevel() < 250 then
+ player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need at least level 250 to enter.")
+ player:teleportTo(fromPosition, true)
+ return false
+ end
+
+ local now, text = os.time(), ""
+ for _, bossName in pairs({ "murcion", "chagorz", "ichgahal", "vemiath" }) do
+ local cooldown = player:kv():scoped("rotten-blood-quest"):scoped(bossName):get("cooldown") or 0
+ if cooldown <= now then
+ text = text .. "\n" .. bossName:titleCase()
+ end
+ end
+
+ if text ~= "" then
+ player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You still need to defeat: " .. text)
+ player:teleportTo(fromPosition, true)
+ return false
+ end
+
+ local taints = player:kv():scoped("rotten-blood-quest"):get("taints") or 0
+ if taints < 4 then
+ player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("You have %i taints.", taints))
+ player:teleportTo(fromPosition, true)
+ return false
+ end
+
+ if entrance.position == position then
+ player:teleportTo(entrance.destination)
+ player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
+ end
+
+ return true
+end
+
+bakragoreEntrance:type("stepin")
+bakragoreEntrance:position(entrance.position)
+bakragoreEntrance:register()
diff --git a/data-otservbr-global/scripts/actions/quests/rotten_blood/sacrifice.lua b/data-otservbr-global/scripts/actions/quests/rotten_blood/sacrifice.lua
new file mode 100644
index 00000000000..dcb1cfef4ab
--- /dev/null
+++ b/data-otservbr-global/scripts/actions/quests/rotten_blood/sacrifice.lua
@@ -0,0 +1,34 @@
+local sacrificialPlate = Action()
+
+function sacrificialPlate.onUse(player, item, fromPosition, target, toPosition, isHotkey)
+ local access = player:kv():scoped("rotten-blood-quest"):get("access") or 0
+ if access > 3 then
+ player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You already have access.")
+ return true
+ end
+
+ if player:getItemCount(32594) < 1 then
+ player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Find the keeper of the sanguine tears and offer his life fluids to the sanguine master of this realm.")
+ return false
+ end
+
+ if access == 1 then
+ player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Reinforce your sacrifice for a blooded tear to the sanguine master of this realm to seal this trade.")
+ player:kv():scoped("rotten-blood-quest"):set("access", 2)
+ return true
+ end
+
+ if player:removeItem(32594, 1) then
+ if access == 2 then
+ player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your sacrifice has been accepted by the sanguine master of this realm.")
+ elseif access == 3 then
+ player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your sacrifices have been accepted by the sanguine master of this realm. Go forth and bedew your root with the waters of life.")
+ end
+ player:kv():scoped("rotten-blood-quest"):set("access", access + 1)
+ end
+
+ return true
+end
+
+sacrificialPlate:id(43891)
+sacrificialPlate:register()
diff --git a/data-otservbr-global/scripts/spells/monster/large_black_ring.lua b/data-otservbr-global/scripts/spells/monster/large_black_ring.lua
new file mode 100644
index 00000000000..8289013ca32
--- /dev/null
+++ b/data-otservbr-global/scripts/spells/monster/large_black_ring.lua
@@ -0,0 +1,35 @@
+local spell = Spell("instant")
+
+local aLarge = {
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 1, 1, 1, 1, 0, 0, 3, 0, 0, 1, 1, 1, 1 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+}
+
+local combatLargeRing = Combat()
+combatLargeRing:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE)
+combatLargeRing:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_BLACKSMOKE)
+combatLargeRing:setArea(createCombatArea(aLarge))
+
+local combats = { combatLargeRing }
+
+function spell.onCastSpell(creature, var)
+ local randomCombat = combats[math.random(#combats)]
+ return randomCombat:execute(creature, var)
+end
+
+spell:name("largeblackring")
+spell:words("###large_black_ring")
+spell:needLearn(true)
+spell:isSelfTarget(true)
+spell:register()
diff --git a/data-otservbr-global/scripts/spells/monster/large_blackportal_ring.lua b/data-otservbr-global/scripts/spells/monster/large_blackportal_ring.lua
new file mode 100644
index 00000000000..f506b1a2790
--- /dev/null
+++ b/data-otservbr-global/scripts/spells/monster/large_blackportal_ring.lua
@@ -0,0 +1,35 @@
+local spell = Spell("instant")
+
+local aLarge = {
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 1, 1, 1, 1, 0, 0, 3, 0, 0, 1, 1, 1, 1 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+}
+
+local combatLargeRing = Combat()
+combatLargeRing:setParameter(COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE)
+combatLargeRing:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA)
+combatLargeRing:setArea(createCombatArea(aLarge))
+
+local combats = { combatLargeRing }
+
+function spell.onCastSpell(creature, var)
+ local randomCombat = combats[math.random(#combats)]
+ return randomCombat:execute(creature, var)
+end
+
+spell:name("largedeathring")
+spell:words("###large_death_ring")
+spell:needLearn(true)
+spell:isSelfTarget(true)
+spell:register()
diff --git a/data-otservbr-global/scripts/spells/monster/large_energy_ring.lua b/data-otservbr-global/scripts/spells/monster/large_energy_ring.lua
new file mode 100644
index 00000000000..f049228927d
--- /dev/null
+++ b/data-otservbr-global/scripts/spells/monster/large_energy_ring.lua
@@ -0,0 +1,35 @@
+local spell = Spell("instant")
+
+local aLarge = {
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 1, 1, 1, 1, 0, 0, 3, 0, 0, 1, 1, 1, 1 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+}
+
+local combatLargeRing = Combat()
+combatLargeRing:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
+combatLargeRing:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT)
+combatLargeRing:setArea(createCombatArea(aLarge))
+
+local combats = { combatLargeRing }
+
+function spell.onCastSpell(creature, var)
+ local randomCombat = combats[math.random(#combats)]
+ return randomCombat:execute(creature, var)
+end
+
+spell:name("largeenergyring")
+spell:words("###large_energy_ring")
+spell:needLearn(true)
+spell:isSelfTarget(true)
+spell:register()
diff --git a/data-otservbr-global/scripts/spells/monster/large_fire_ring.lua b/data-otservbr-global/scripts/spells/monster/large_fire_ring.lua
new file mode 100644
index 00000000000..7c14843c640
--- /dev/null
+++ b/data-otservbr-global/scripts/spells/monster/large_fire_ring.lua
@@ -0,0 +1,35 @@
+local spell = Spell("instant")
+
+local aLarge = {
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 1, 1, 1, 1, 0, 0, 3, 0, 0, 1, 1, 1, 1 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+}
+
+local combatLargeRing = Combat()
+combatLargeRing:setParameter(COMBAT_PARAM_TYPE, COMBAT_FIREDAMAGE)
+combatLargeRing:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_FIREATTACK)
+combatLargeRing:setArea(createCombatArea(aLarge))
+
+local combats = { combatLargeRing }
+
+function spell.onCastSpell(creature, var)
+ local randomCombat = combats[math.random(#combats)]
+ return randomCombat:execute(creature, var)
+end
+
+spell:name("largefirering")
+spell:words("###large_fire_ring")
+spell:needLearn(true)
+spell:isSelfTarget(true)
+spell:register()
diff --git a/data-otservbr-global/scripts/spells/monster/large_holy_ring.lua b/data-otservbr-global/scripts/spells/monster/large_holy_ring.lua
new file mode 100644
index 00000000000..50b05444a66
--- /dev/null
+++ b/data-otservbr-global/scripts/spells/monster/large_holy_ring.lua
@@ -0,0 +1,35 @@
+local spell = Spell("instant")
+
+local aLarge = {
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 1, 1, 1, 1, 0, 0, 3, 0, 0, 1, 1, 1, 1 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+}
+
+local combatLargeRing = Combat()
+combatLargeRing:setParameter(COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE)
+combatLargeRing:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_CONST_ME_HOLYAREA)
+combatLargeRing:setArea(createCombatArea(aLarge))
+
+local combats = { combatLargeRing }
+
+function spell.onCastSpell(creature, var)
+ local randomCombat = combats[math.random(#combats)]
+ return randomCombat:execute(creature, var)
+end
+
+spell:name("largeholyring")
+spell:words("###large_holy_ring")
+spell:needLearn(true)
+spell:isSelfTarget(true)
+spell:register()
diff --git a/data-otservbr-global/scripts/spells/monster/large_ice_ring.lua b/data-otservbr-global/scripts/spells/monster/large_ice_ring.lua
new file mode 100644
index 00000000000..ef1868f9585
--- /dev/null
+++ b/data-otservbr-global/scripts/spells/monster/large_ice_ring.lua
@@ -0,0 +1,35 @@
+local spell = Spell("instant")
+
+local aLarge = {
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 1, 1, 1, 1, 0, 0, 3, 0, 0, 1, 1, 1, 1 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+}
+
+local combatLargeRing = Combat()
+combatLargeRing:setParameter(COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE)
+combatLargeRing:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ICEAREA)
+combatLargeRing:setArea(createCombatArea(aLarge))
+
+local combats = { combatLargeRing }
+
+function spell.onCastSpell(creature, var)
+ local randomCombat = combats[math.random(#combats)]
+ return randomCombat:execute(creature, var)
+end
+
+spell:name("largeicering")
+spell:words("###large_ice_ring")
+spell:needLearn(true)
+spell:isSelfTarget(true)
+spell:register()
diff --git a/data-otservbr-global/scripts/spells/monster/large_pink_ring.lua b/data-otservbr-global/scripts/spells/monster/large_pink_ring.lua
new file mode 100644
index 00000000000..1bb28cefeb9
--- /dev/null
+++ b/data-otservbr-global/scripts/spells/monster/large_pink_ring.lua
@@ -0,0 +1,35 @@
+local spell = Spell("instant")
+
+local aLarge = {
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 1, 1, 1, 1, 0, 0, 3, 0, 0, 1, 1, 1, 1 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+}
+
+local combatLargeRing = Combat()
+combatLargeRing:setParameter(COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
+combatLargeRing:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ELECTRICALSPARK)
+combatLargeRing:setArea(createCombatArea(aLarge))
+
+local combats = { combatLargeRing }
+
+function spell.onCastSpell(creature, var)
+ local randomCombat = combats[math.random(#combats)]
+ return randomCombat:execute(creature, var)
+end
+
+spell:name("largepinkring")
+spell:words("###large_pink_ring")
+spell:needLearn(true)
+spell:isSelfTarget(true)
+spell:register()
diff --git a/data-otservbr-global/scripts/spells/monster/large_poison_ring.lua b/data-otservbr-global/scripts/spells/monster/large_poison_ring.lua
new file mode 100644
index 00000000000..98737e088df
--- /dev/null
+++ b/data-otservbr-global/scripts/spells/monster/large_poison_ring.lua
@@ -0,0 +1,35 @@
+local spell = Spell("instant")
+
+local aLarge = {
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 1, 1, 1, 1, 0, 0, 3, 0, 0, 1, 1, 1, 1 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+}
+
+local combatLargeRing = Combat()
+combatLargeRing:setParameter(COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE)
+combatLargeRing:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_GREEN_RINGS)
+combatLargeRing:setArea(createCombatArea(aLarge))
+
+local combats = { combatLargeRing }
+
+function spell.onCastSpell(creature, var)
+ local randomCombat = combats[math.random(#combats)]
+ return randomCombat:execute(creature, var)
+end
+
+spell:name("largepoisonring")
+spell:words("###large_poison_ring")
+spell:needLearn(true)
+spell:isSelfTarget(true)
+spell:register()
diff --git a/data-otservbr-global/scripts/spells/monster/large_purple_ring_smoke.lua b/data-otservbr-global/scripts/spells/monster/large_purple_ring_smoke.lua
new file mode 100644
index 00000000000..7d7d40c26c3
--- /dev/null
+++ b/data-otservbr-global/scripts/spells/monster/large_purple_ring_smoke.lua
@@ -0,0 +1,35 @@
+local spell = Spell("instant")
+
+local aLarge = {
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 1, 1, 1, 1, 0, 0, 3, 0, 0, 1, 1, 1, 1 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+}
+
+local combatLargeRing = Combat()
+combatLargeRing:setParameter(COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE)
+combatLargeRing:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_PURPLESMOKE)
+combatLargeRing:setArea(createCombatArea(aLarge))
+
+local combats = { combatLargeRing }
+
+function spell.onCastSpell(creature, var)
+ local randomCombat = combats[math.random(#combats)]
+ return randomCombat:execute(creature, var)
+end
+
+spell:name("largepurplering")
+spell:words("###large_purple_ring")
+spell:needLearn(true)
+spell:isSelfTarget(true)
+spell:register()
diff --git a/data-otservbr-global/scripts/spells/monster/large_red_ring.lua b/data-otservbr-global/scripts/spells/monster/large_red_ring.lua
new file mode 100644
index 00000000000..0103ae5c31b
--- /dev/null
+++ b/data-otservbr-global/scripts/spells/monster/large_red_ring.lua
@@ -0,0 +1,35 @@
+local spell = Spell("instant")
+
+local aLarge = {
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 1, 1, 1, 1, 0, 0, 3, 0, 0, 1, 1, 1, 1 },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
+}
+
+local combatLargeRing = Combat()
+combatLargeRing:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)
+combatLargeRing:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_REDSMOKE)
+combatLargeRing:setArea(createCombatArea(aLarge))
+
+local combats = { combatLargeRing }
+
+function spell.onCastSpell(creature, var)
+ local randomCombat = combats[math.random(#combats)]
+ return randomCombat:execute(creature, var)
+end
+
+spell:name("largeredring")
+spell:words("###large_red_ring")
+spell:needLearn(true)
+spell:isSelfTarget(true)
+spell:register()
diff --git a/data-otservbr-global/world/otservbr-monster.xml b/data-otservbr-global/world/otservbr-monster.xml
index 424e4210b80..2fe127164f3 100644
--- a/data-otservbr-global/world/otservbr-monster.xml
+++ b/data-otservbr-global/world/otservbr-monster.xml
@@ -162462,6 +162462,9 @@
+
+
+
@@ -162487,6 +162490,15 @@
+
+
+
+
+
+
+
+
+
@@ -162502,6 +162514,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162518,6 +162542,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162534,6 +162573,15 @@
+
+
+
+
+
+
+
+
+
@@ -162553,12 +162601,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162574,9 +162637,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162590,6 +162674,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162603,6 +162699,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162628,11 +162742,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162659,6 +162788,15 @@
+
+
+
+
+
+
+
+
+
@@ -162684,6 +162822,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162704,6 +162857,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162716,19 +162881,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162747,15 +162951,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162767,6 +163004,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162776,18 +163040,105 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162795,21 +163146,96 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162817,6 +163243,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162831,6 +163278,15 @@
+
+
+
+
+
+
+
+
+
@@ -162840,30 +163296,156 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162876,6 +163458,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162885,6 +163497,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162897,10 +163533,136 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162908,6 +163670,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162917,15 +163703,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -162936,29 +163773,167 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
-
-
+
+
-
-
-
+
+
@@ -162970,6 +163945,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163232,10 +164222,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163263,6 +164271,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163270,12 +164302,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163302,6 +164364,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163309,9 +164392,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163326,18 +164427,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163368,11 +164523,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163382,9 +164579,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163409,6 +164633,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163418,14 +164657,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163464,15 +164733,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163497,12 +164796,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163512,15 +164841,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163530,6 +164892,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163541,12 +164951,141 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163561,12 +165100,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163582,12 +165157,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163597,18 +165184,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163616,6 +165248,12 @@
+
+
+
+
+
+
@@ -163627,6 +165265,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163639,24 +165289,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163666,6 +165361,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163680,6 +165393,15 @@
+
+
+
+
+
+
+
+
+
@@ -163689,9 +165411,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163702,6 +165469,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163712,15 +165491,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163732,6 +165547,15 @@
+
+
+
+
+
+
+
+
+
@@ -163741,12 +165565,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -163788,6 +165630,12 @@
+
+
+
+
+
+
@@ -163804,6 +165652,9 @@
+
+
+
@@ -163824,6 +165675,9 @@
+
+
+
@@ -173593,6 +175447,9 @@
+
+
+
@@ -173611,9 +175468,18 @@
+
+
+
+
+
+
+
+
+
@@ -173640,18 +175506,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -173682,6 +175563,15 @@
+
+
+
+
+
+
+
+
+
@@ -173698,6 +175588,12 @@
+
+
+
+
+
+
@@ -173729,10 +175625,16 @@
+
+
+
+
+
+
@@ -173755,10 +175657,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -173767,6 +175699,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -173783,6 +175748,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -173795,9 +175832,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -173821,14 +175885,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -173839,6 +175936,9 @@
+
+
+
@@ -173851,15 +175951,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -173875,6 +175993,9 @@
+
+
+
@@ -173882,6 +176003,9 @@
+
+
+
@@ -173899,6 +176023,12 @@
+
+
+
+
+
+
@@ -173924,6 +176054,12 @@
+
+
+
+
+
+
@@ -173942,12 +176078,21 @@
+
+
+
+
+
+
+
+
+
@@ -173961,6 +176106,15 @@
+
+
+
+
+
+
+
+
+
@@ -174451,6 +176605,9 @@
+
+
+
@@ -174478,9 +176635,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -174516,9 +176697,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -174558,6 +176769,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -174602,9 +176837,15 @@
+
+
+
+
+
+
@@ -174614,6 +176855,12 @@
+
+
+
+
+
+
@@ -174678,9 +176925,15 @@
+
+
+
+
+
+
@@ -174731,6 +176984,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -174770,6 +177050,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -174799,6 +177091,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -174837,12 +177141,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -174859,6 +177178,9 @@
+
+
+
@@ -174870,6 +177192,12 @@
+
+
+
+
+
+
@@ -174918,6 +177246,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -174928,18 +177268,27 @@
+
+
+
+
+
+
+
+
+
@@ -174952,13 +177301,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -175014,9 +177378,18 @@
+
+
+
+
+
+
+
+
+
@@ -175052,9 +177425,18 @@
+
+
+
+
+
+
+
+
+
@@ -175064,9 +177446,18 @@
+
+
+
+
+
+
+
+
+
@@ -175091,18 +177482,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -175130,13 +177560,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -175156,12 +177601,18 @@
+
+
+
+
+
+
@@ -175169,6 +177620,9 @@
+
+
+
@@ -175180,6 +177634,9 @@
+
+
+
@@ -175193,6 +177650,9 @@
+
+
+
diff --git a/data-otservbr-global/world/otservbr-npc.xml b/data-otservbr-global/world/otservbr-npc.xml
index 5c53601aa9c..897f70baa1d 100644
--- a/data-otservbr-global/world/otservbr-npc.xml
+++ b/data-otservbr-global/world/otservbr-npc.xml
@@ -1893,6 +1893,9 @@
+
+
+
@@ -2451,6 +2454,9 @@
+
+
+
@@ -2863,6 +2869,9 @@
+
+
+
diff --git a/data/items/items.xml b/data/items/items.xml
index c1b8e8a63ba..17bc96b1bad 100644
--- a/data/items/items.xml
+++ b/data/items/items.xml
@@ -74883,21 +74883,12 @@ Granted by TibiaGoals.com"/>
-
-
- -
-
-
-
- -
-
-
-
- -
-
+
-
+
+
-
- -
-
+
-
+
-
@@ -74916,6 +74907,22 @@ Granted by TibiaGoals.com"/>
-
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
-
@@ -74947,6 +74954,190 @@ Granted by TibiaGoals.com"/>
+ -
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
-
@@ -75117,6 +75308,196 @@ Granted by TibiaGoals.com"/>
+ -
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
-
@@ -75850,6 +76231,9 @@ Granted by TibiaGoals.com"/>
+ -
+
+
-
diff --git a/data/libs/tables/doors.lua b/data/libs/tables/doors.lua
index c87e8cb01ec..3daafd890b9 100644
--- a/data/libs/tables/doors.lua
+++ b/data/libs/tables/doors.lua
@@ -225,6 +225,7 @@ QuestDoorTable = {
{ closedDoor = 36547, openDoor = 36548 },
{ closedDoor = 39351, openDoor = 39353 },
{ closedDoor = 39352, openDoor = 39354 },
+ { closedDoor = 42744, openDoor = 42745 },
}
-- Level doors.