diff --git a/scripts/enum/mob_skill.lua b/scripts/enum/mob_skill.lua index 16f3f7e1bc5..56cfbc12c90 100644 --- a/scripts/enum/mob_skill.lua +++ b/scripts/enum/mob_skill.lua @@ -277,10 +277,15 @@ xi.mobSkill = GRAVE_REEL = 472, + HORROR_CLOUD = 479, + PETRIFACTIVE_BREATH = 480, CHARGED_WHISKER = 483, + BLACK_CLOUD = 484, + BLOOD_SABER = 485, + WHIP_TONGUE = 486, TRANSMOGRIFICATION = 487, -- Mammet-800 @@ -1006,6 +1011,8 @@ xi.mobSkill = VAMPIRIC_ROOT = 1793, + MALEDICTION = 1795, + BOILING_POINT = 1822, XENOGLOSSIA = 1823, AMORPHIC_SPIKES = 1824, diff --git a/scripts/zones/Arrapago_Reef/IDs.lua b/scripts/zones/Arrapago_Reef/IDs.lua index 81bcdc6b745..c12936b67d3 100644 --- a/scripts/zones/Arrapago_Reef/IDs.lua +++ b/scripts/zones/Arrapago_Reef/IDs.lua @@ -43,6 +43,7 @@ zones[xi.zone.ARRAPAGO_REEF] = MEMBER_TOO_FAR = 8489, -- One or more party members are too far away from the entrance. Unable to enter area. MEDUSA_ENGAGE = 8599, -- Foolish two-legs... Have you forgotten the terrible power of the gorgons you created? It is time you were reminded... MEDUSA_DEATH = 8600, -- No... I cannot leave my sisters... + FOREBODING = 8602, -- You feel an eerie sense of foreboding... GLITTERING_FRAGMENTS = 8923, -- Minute glittering fragments are scattered all over... STIFLING_STENCH = 8936, -- A stifling stench pervades the air... SLIMY_TOUCH = 8941, -- The ground here is slimy to the touch... diff --git a/scripts/zones/Arrapago_Reef/mobs/Bloody_Bones.lua b/scripts/zones/Arrapago_Reef/mobs/Bloody_Bones.lua index 0059bcdd0e5..55c60d1dfb2 100644 --- a/scripts/zones/Arrapago_Reef/mobs/Bloody_Bones.lua +++ b/scripts/zones/Arrapago_Reef/mobs/Bloody_Bones.lua @@ -1,12 +1,24 @@ ----------------------------------- -- Area: Arrapago Reef -- NM: Bloody Bones +-- !pos 136.234 -6.831 468.779 54 +-- TODO: Get more data on the rate at which he uses Malediction. Below 20%, he seems to heavily favor it. 75% is an estimate based on current captures. +----------------------------------- +mixins = { require('scripts/mixins/job_special') } ----------------------------------- local ID = zones[xi.zone.ARRAPAGO_REEF] ----------------------------------- ---@type TMobEntity local entity = {} +-- His normal (non-Malediction) TP moves; Malediction usage is handled in onMobMobskillChoose +local normalTpMoves = +{ + xi.mobSkill.HORROR_CLOUD, + xi.mobSkill.BLACK_CLOUD, + xi.mobSkill.BLOOD_SABER, +} + entity.spawnPoints = { { x = 136.000, y = -6.000, z = 476.000 } @@ -17,6 +29,59 @@ entity.phList = [ID.mob.BLOODY_BONES - 1] = ID.mob.BLOODY_BONES, -- 136.234 -6.831 468.779 } +entity.onMobInitialize = function(mob) + mob:addImmunity(xi.immunity.DARK_SLEEP) + mob:addImmunity(xi.immunity.LIGHT_SLEEP) + mob:addImmunity(xi.immunity.TERROR) + mob:addImmunity(xi.immunity.PLAGUE) + mob:addImmunity(xi.immunity.PETRIFY) +end + +entity.onMobSpawn = function(mob) + mob:setMobMod(xi.mobMod.BASE_DAMAGE_MULTIPLIER, 150) + mob:setMobMod(xi.mobMod.AOE_HIT_ALL, 1) +end + +entity.onMobSpellChoose = function(mob, target, spellId) + local spellList = + { + [ 1] = { xi.magic.spell.BIND, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.BIND, 0, 100 }, + [ 2] = { xi.magic.spell.STUN, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.STUN, 0, 100 }, + [ 3] = { xi.magic.spell.THUNDER_II, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [ 4] = { xi.magic.spell.ABSORB_VIT, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.VIT_DOWN, 0, 100 }, + [ 5] = { xi.magic.spell.DRAIN, target, false, xi.action.type.DRAIN_HP, nil, 0, 100 }, + [ 6] = { xi.magic.spell.ABSORB_DEX, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.DEX_DOWN, 0, 100 }, + [ 7] = { xi.magic.spell.ABSORB_INT, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.INT_DOWN, 0, 100 }, + [ 8] = { xi.magic.spell.BIO_II, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.BIO, 4, 100 }, + [ 9] = { xi.magic.spell.ABSORB_AGI, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.AGI_DOWN, 0, 100 }, + [10] = { xi.magic.spell.ABSORB_STR, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.STR_DOWN, 0, 100 }, + [11] = { xi.magic.spell.ABSORB_TP, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [12] = { xi.magic.spell.POISON_II, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.POISON, 0, 100 }, + [13] = { xi.magic.spell.ASPIR, target, false, xi.action.type.DRAIN_MP, nil, 0, 100 }, + [14] = { xi.magic.spell.BLIZZARD_II, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [15] = { xi.magic.spell.SLEEP_II, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.SLEEP_I, 2, 100 }, + [16] = { xi.magic.spell.WATER_III, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [17] = { xi.magic.spell.AERO_II, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [18] = { xi.magic.spell.STONE_III, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + } + + return xi.combat.behavior.chooseAction(mob, target, nil, spellList) +end + +entity.onMobMobskillChoose = function(mob, target, skillId) + -- At or above 20% HP his TP moves (Malediction included) shuffle normally + if mob:getHPP() >= 20 then + return skillId + end + + -- Below 20% HP: Malediction 75% of the time, his other TP moves 25% of the time + if math.random(1, 100) <= 75 then + return xi.mobSkill.MALEDICTION + end + + return normalTpMoves[math.random(1, #normalTpMoves)] +end + entity.onMobDeath = function(mob, player, optParams) xi.hunts.checkHunt(mob, player, 472) end diff --git a/scripts/zones/Arrapago_Reef/mobs/Lamia_No19.lua b/scripts/zones/Arrapago_Reef/mobs/Lamia_No19.lua index e52c1e42919..7ac2e5089bc 100644 --- a/scripts/zones/Arrapago_Reef/mobs/Lamia_No19.lua +++ b/scripts/zones/Arrapago_Reef/mobs/Lamia_No19.lua @@ -1,19 +1,350 @@ ----------------------------------- -- Area: Arrapago Reef --- Mob: Lamia No.19 +-- NM: Lamia No.19 +-- TODO: On retail, she walks randomly in her spawn zones rather than using set points. The set points are used here to avoid +-- complications with pathfinding and her long roam range. +-- TODO: Get more data on the reveal chance rate. 80% is an estimate based on current captures. +-- TODO: Get more data on the maximum respawn time. Minimum is 1 hour based on current captures, but more data is needed. ----------------------------------- mixins = { require('scripts/mixins/weapon_break') } ----------------------------------- +local ID = zones[xi.zone.ARRAPAGO_REEF] + +local moveInterval = 25 -- seconds between advancing to the next patrol point + +-- 'state' local var: 0 = dormant (invisible, patrolling), 1 = revealed (awaiting engagement), 2 = returning home + +-- Patrol zones. She spawns in one at random, starts on its first point, walks the list to the end, then back up, and repeats +local patrolZones = +{ + { -- Zone 1 + { x = -140.3979, y = -7.5625, z = 129.6947 }, + { x = -151.5618, y = -7.5669, z = 133.4263 }, + { x = -159.6965, y = -4.0674, z = 142.4664 }, + { x = -147.8239, y = -3.9370, z = 143.8264 }, + { x = -132.7979, y = -4.1487, z = 142.3289 }, + { x = -116.7645, y = -5.6650, z = 138.4146 }, + { x = -106.3411, y = -3.6548, z = 149.6426 }, + { x = -95.9528, y = -7.0264, z = 157.3188 }, + { x = -97.9981, y = -8.2839, z = 177.5508 }, + { x = -95.9604, y = -6.5235, z = 194.4670 }, + { x = -97.5012, y = -6.2962, z = 209.2726 }, + { x = -84.0119, y = -6.6560, z = 216.9704 }, + }, + { -- Zone 2 + { x = -70.4526, y = -3.4229, z = 225.8736 }, + { x = -55.8334, y = -6.8534, z = 234.8286 }, + { x = -52.0121, y = -7.6663, z = 252.0792 }, + { x = -36.6158, y = -7.1406, z = 255.2419 }, + { x = -18.6769, y = -4.2378, z = 257.9763 }, + { x = -23.2517, y = -6.7339, z = 240.1379 }, + { x = -29.7112, y = -7.3039, z = 226.7537 }, + { x = -23.0620, y = -8.6800, z = 213.3530 }, + { x = -27.1148, y = -8.1091, z = 204.9024 }, + { x = -9.3409, y = -4.1911, z = 209.8858 }, + { x = -6.8611, y = -3.6151, z = 227.8160 }, + }, + { -- Zone 3 + { x = 24.1552, y = -4.3124, z = 222.5897 }, + { x = 29.0236, y = -7.6649, z = 211.4547 }, + { x = 18.9880, y = -4.6938, z = 199.3556 }, + { x = 7.5865, y = -3.9338, z = 190.0146 }, + { x = 23.4894, y = -8.4546, z = 181.0779 }, + { x = 26.4053, y = -7.4731, z = 163.9737 }, + { x = 16.8353, y = -7.3900, z = 155.6682 }, + { x = 0.1742, y = -1.9985, z = 159.1774 }, + }, +} + +-- Flat list of every patrol point (all zones, in order), plus the allPoints index of each zone's first point. On the way +-- home she enters this network at the nearest point and walks it back to her own zone's first point, so every leg is a +-- short, walkable hop between adjacent points instead of one long straight line across the map +local allPoints = {} +local zoneStart = {} +for _, zonePoints in ipairs(patrolZones) do + zoneStart[#zoneStart + 1] = #allPoints + 1 + for _, point in ipairs(zonePoints) do + allPoints[#allPoints + 1] = point + end +end + ---@type TMobEntity local entity = {} +-- Tracks deaths she has already handled. Each death gets one reveal chance, evaluated once at the moment of death, so a +-- lingering corpse can't re-trigger. An entry is cleared once that player is alive again (their next death is eligible) +local rolledDeaths = {} + +-- Hide her and (re)start the patrol from the first point of a zone. Pass a zoneIndex to keep her in the zone she just returned to; omit it on first spawn to pick a zone at random +local function goDormant(mob, zoneIndex) + zoneIndex = zoneIndex or math.random(1, #patrolZones) + + mob:setLocalVar('zone', zoneIndex) + mob:setLocalVar('state', 0) + mob:setLocalVar('appearTime', 0) + mob:setLocalVar('wpIndex', 1) -- current patrol point (she starts on point 1) + mob:setLocalVar('wpReverse', 0) -- 0 = walking down the list, 1 = walking back up + mob:setLocalVar('nextMoveTime', GetSystemTime() + moveInterval) + + mob:setStatus(xi.status.INVISIBLE) + mob:hideHP(true) + mob:hideName(true) + mob:setUntargetable(true) + mob:setAggressive(false) + mob:setMobMod(xi.mobMod.ALWAYS_AGGRO, 0) + mob:setTrueDetection(false) + mob:setMobMod(xi.mobMod.NO_MOVE, 0) + + -- Start on the zone's first point; movement is driven in onMobRoam + local first = patrolZones[zoneIndex][1] + mob:clearPath() + mob:setPos(first.x, first.y, first.z) +end + +-- Index in allPoints of the patrol point nearest her current position +local function nearestIndexInAll(mob) + local bestIdx, bestDist = 1, nil + for i, p in ipairs(allPoints) do + local d = mob:checkDistance(p.x, p.y, p.z) + if not bestDist or d < bestDist then + bestIdx, bestDist = i, d + end + end + + return bestIdx +end + +-- Disengage/give up: enter the patrol-point network at the nearest point and walk it back home +local function startReturningHome(mob) + -- The fight is over - send any summoned skeletons away so the next engage gets a fresh pair spawned at her side + local mobId = mob:getID() + DespawnMob(mobId + 1) + DespawnMob(mobId + 2) + + mob:setLocalVar('state', 2) + mob:setLocalVar('returnIndex', nearestIndexInAll(mob)) -- enter the network at the nearest point + mob:setLocalVar('returnPauseUntil', 0) + mob:setMobMod(xi.mobMod.NO_MOVE, 0) + mob:clearPath() + + local wp = allPoints[mob:getLocalVar('returnIndex')] + mob:pathThrough({ wp.x, wp.y, wp.z }) +end + +-- Reveal: Teleport onto the corpse, reveal herself, and become aggressive with true sight +local function reveal(mob, player) + mob:clearPath() + mob:setMobMod(xi.mobMod.NO_MOVE, 1) + mob:setPos(player:getXPos(), player:getYPos(), player:getZPos()) + + mob:setStatus(xi.status.UPDATE) + mob:hideHP(false) + mob:hideName(false) + mob:setUntargetable(false) + + -- While visible she is always aggressive and has true sight + mob:setAggressive(true) + mob:setMobMod(xi.mobMod.ALWAYS_AGGRO, 1) + mob:setMobMod(xi.mobMod.DETECTION, xi.detects.SIGHT) + mob:setTrueDetection(true) + + mob:setLocalVar('state', 1) + mob:setLocalVar('appearTime', GetSystemTime()) +end + +-- Show the foreboding message (not spoken by her - just a displayed area message) to every player within 30 yalms of the death +local function broadcastForeboding(deadPlayer) + local zone = deadPlayer:getZone() + if not zone then + return + end + + for _, p in pairs(zone:getPlayers()) do + if p:checkDistance(deadPlayer) <= 30 then -- the foreboding message is displayed within 30 yalms + p:messageSpecial(ID.text.FOREBODING) + end + end +end + +-- Watch for a nearby player death; returns true if she is revealed +local function checkForDeath(mob) + local zone = mob:getZone() + if not zone then + return false + end + + for _, player in pairs(zone:getPlayers()) do + local pid = player:getID() + + if not player:isDead() then + -- Player is alive again; forget the handled death so a later one is eligible for a fresh chance + rolledDeaths[pid] = nil + elseif not rolledDeaths[pid] then + -- First tick we have seen this death: it gets exactly one chance, right now. Mark it immediately whatever the + -- outcome, so a lingering corpse can never re-trigger; she only reacts to a death that happens close to her + rolledDeaths[pid] = true + + if mob:checkDistance(player) <= 15 then -- death happened within 15 yalms of her + -- Show the foreboding message (not spoken by her - just displayed) to everyone near the death + broadcastForeboding(player) + + -- 80% chance she answers it (estimate from current captures; needs more data for a precise rate) + if math.random(100) <= 80 then + reveal(mob, player) + return true + end + end + end + end + + return false +end + +-- Advance one patrol point every moveInterval seconds, going down the zone's list to the end and back up to the start +local function drivePatrol(mob) + if GetSystemTime() < mob:getLocalVar('nextMoveTime') then + return + end + + local points = patrolZones[mob:getLocalVar('zone')] + local idx = mob:getLocalVar('wpIndex') + local reverse = mob:getLocalVar('wpReverse') + + if reverse == 0 then + if idx >= #points then + reverse = 1 -- reached the end; turn around + idx = idx - 1 + else + idx = idx + 1 + end + else + if idx <= 1 then + reverse = 0 -- reached the start; turn around + idx = idx + 1 + else + idx = idx - 1 + end + end + + mob:setLocalVar('wpIndex', idx) + mob:setLocalVar('wpReverse', reverse) + mob:setLocalVar('nextMoveTime', GetSystemTime() + moveInterval) + + local wp = points[idx] + mob:pathThrough({ wp.x, wp.y, wp.z }) +end + +entity.onMobInitialize = function(mob) + mob:addImmunity(xi.immunity.SILENCE) + mob:addImmunity(xi.immunity.TERROR) + mob:addImmunity(xi.immunity.PLAGUE) + mob:addImmunity(xi.immunity.LIGHT_SLEEP) + mob:addImmunity(xi.immunity.PETRIFY) +end + +entity.onMobSpawn = function(mob) + -- Don't let the engine drag her back to her DB spawn point (with WALLHACK) while she patrols far from it + mob:setMobMod(xi.mobMod.DONT_ROAM_HOME, 1) + goDormant(mob) + mob:setMod(xi.mod.POWER_MULTIPLIER_SPELL, 20) + mob:setMobMod(xi.mobMod.BASE_DAMAGE_MULTIPLIER, 150) +end + +entity.onMobRoam = function(mob) + local state = mob:getLocalVar('state') + + -- Dormant and invisible: walk the patrol and watch for a nearby death + if state == 0 then + if not checkForDeath(mob) then + drivePatrol(mob) + end + + -- Revealed but never engaged: after the idle timer she gives up and walks home + elseif state == 1 then + if GetSystemTime() - mob:getLocalVar('appearTime') >= 120 then -- 2 minutes + startReturningHome(mob) + end + + -- Returning: walk the patrol-point network back to her zone's first point, pausing briefly at each, then re-hide + elseif state == 2 then + local idx = mob:getLocalVar('returnIndex') + local wp = allPoints[idx] + + if mob:checkDistance(wp.x, wp.y, wp.z) <= 3 then -- reached the current point + local pauseUntil = mob:getLocalVar('returnPauseUntil') + if pauseUntil == 0 then + mob:setLocalVar('returnPauseUntil', GetSystemTime() + 3) -- pause ~3s before moving on + elseif GetSystemTime() >= pauseUntil then + mob:setLocalVar('returnPauseUntil', 0) + + local target = zoneStart[mob:getLocalVar('zone')] + if idx == target then + goDormant(mob, mob:getLocalVar('zone')) -- back at her first point; hide & patrol + else + idx = idx + (target > idx and 1 or -1) -- step one point toward home + mob:setLocalVar('returnIndex', idx) + + local nxt = allPoints[idx] + mob:pathThrough({ nxt.x, nxt.y, nxt.z }) + end + end + elseif not mob:isFollowingPath() then + mob:pathThrough({ wp.x, wp.y, wp.z }) -- path interrupted; resume + end + end +end + entity.onMobEngage = function(mob, target) + -- She was holding position: let her move now that she fights + mob:setMobMod(xi.mobMod.NO_MOVE, 0) + + -- Summon two Lamia's Skeleton next to her. Their DB spawn points sit by her original spawn, far from where she now + -- reveals, so place them at her side before spawning or they would appear across the zone local mobId = mob:getID() + local x, y, z = mob:getXPos(), mob:getYPos(), mob:getZPos() + + GetMobByID(mobId + 1):setSpawn(x + 2, y, z) + GetMobByID(mobId + 2):setSpawn(x - 2, y, z) SpawnMob(mobId + 1):updateEnmity(target) SpawnMob(mobId + 2):updateEnmity(target) end -entity.onMobDeath = function(mob, player, optParams) +entity.onMobSpellChoose = function(mob, target, spellId) + local spellList = + { + [ 1] = { xi.magic.spell.SLEEPGA_II, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.SLEEP_I, 2, 100 }, + [ 2] = { xi.magic.spell.BLIND, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.BLINDNESS, 0, 100 }, + [ 3] = { xi.magic.spell.ASPIR, target, false, xi.action.type.DRAIN_MP, nil, 0, 100 }, + [ 4] = { xi.magic.spell.STONE_IV, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [ 5] = { xi.magic.spell.BIO_II, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.BIO, 4, 100 }, + [ 6] = { xi.magic.spell.ICE_SPIKES, mob, false, xi.action.type.ENHANCING_FORCE_SELF, xi.effect.ICE_SPIKES, 0, 100 }, + [ 7] = { xi.magic.spell.BIND, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.BIND, 0, 100 }, + [ 8] = { xi.magic.spell.FIRE_IV, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [ 9] = { xi.magic.spell.POISONGA_II, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.POISON, 0, 100 }, + [10] = { xi.magic.spell.SLEEPGA, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.SLEEP_I, 1, 100 }, + [11] = { xi.magic.spell.FLOOD, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [12] = { xi.magic.spell.WATERGA_III, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [13] = { xi.magic.spell.AERO_IV, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [14] = { xi.magic.spell.FIRAGA_III, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [15] = { xi.magic.spell.WATER_IV, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [16] = { xi.magic.spell.BLIZZARD_IV, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + } + + return xi.combat.behavior.chooseAction(mob, target, nil, spellList) +end + +entity.onMobDisengage = function(mob) + -- Combat ended (the player died fighting her, or she lost her target). She walks back along her zone's points; arrival is handled in onMobRoam + startReturningHome(mob) +end + +entity.onMobDespawn = function(mob) + -- She is never despawned by script, so this only runs when she is killed. Take any summoned skeletons with her and respawn her in 1-3 hours + local mobId = mob:getID() + DespawnMob(mobId + 1) + DespawnMob(mobId + 2) + + mob:setRespawnTime(math.random(3600, 10800)) -- respawn in 1-3 hours end return entity diff --git a/scripts/zones/Arrapago_Reef/mobs/Lamias_Skeleton.lua b/scripts/zones/Arrapago_Reef/mobs/Lamias_Skeleton.lua index 7b3078a3d87..8a4f59f9d3d 100644 --- a/scripts/zones/Arrapago_Reef/mobs/Lamias_Skeleton.lua +++ b/scripts/zones/Arrapago_Reef/mobs/Lamias_Skeleton.lua @@ -6,10 +6,15 @@ local entity = {} entity.onMobInitialize = function(mob) - mob:setMobMod(xi.mobMod.IDLE_DESPAWN, 180) + mob:addImmunity(xi.immunity.DARK_SLEEP) + mob:addImmunity(xi.immunity.LIGHT_SLEEP) + mob:addImmunity(xi.immunity.PETRIFY) + mob:addImmunity(xi.immunity.TERROR) + mob:addImmunity(xi.immunity.PLAGUE) end -entity.onMobDeath = function(mob, player, optParams) +entity.onMobSpawn = function(mob) + mob:setMobMod(xi.mobMod.BASE_DAMAGE_MULTIPLIER, 150) end return entity diff --git a/sql/mob_groups.sql b/sql/mob_groups.sql index d440350b64e..648256524d5 100644 --- a/sql/mob_groups.sql +++ b/sql/mob_groups.sql @@ -2951,7 +2951,7 @@ INSERT INTO `mob_groups` VALUES (44,5195,54,'Draugar_Servant_blm',960,0,702,0,0, INSERT INTO `mob_groups` VALUES (45,5196,54,'Draugar_Servant_drg',960,0,702,0,0,0,NULL); INSERT INTO `mob_groups` VALUES (46,2330,54,'Lamia_Deathdancer',960,0,1485,0,0,0,NULL); INSERT INTO `mob_groups` VALUES (47,5197,54,'Draugar_Servant_thf',960,0,702,0,0,0,NULL); -INSERT INTO `mob_groups` VALUES (48,465,54,'Bloody_Bones',0,32,306,0,0,0,NULL); +INSERT INTO `mob_groups` VALUES (48,465,54,'Bloody_Bones',0,32,306,13000,0,0,NULL); INSERT INTO `mob_groups` VALUES (49,2629,54,'Merrow_Songstress',960,0,1657,0,0,0,NULL); INSERT INTO `mob_groups` VALUES (50,2617,54,'Merrow_Bladedancer',960,0,1657,0,0,0,NULL); INSERT INTO `mob_groups` VALUES (51,2043,54,'Ice_Elemental',960,4,1347,0,0,0,NULL); @@ -2989,8 +2989,8 @@ INSERT INTO `mob_groups` VALUES (82,2354,54,'Lamia_Palace_Guard_rng',0,128,0,0,0 INSERT INTO `mob_groups` VALUES (83,2606,54,'Medusa',259200,0,1651,55000,0,0,NULL); INSERT INTO `mob_groups` VALUES (84,2331,54,'Lamia_Exon',0,128,0,0,0,0,NULL); INSERT INTO `mob_groups` VALUES (85,3057,54,'Ornery_Orobon',0,128,0,0,0,0,NULL); -INSERT INTO `mob_groups` VALUES (86,2345,54,'Lamia_No19',0,128,2996,18000,9000,0,NULL); -INSERT INTO `mob_groups` VALUES (87,2360,54,'Lamias_Skeleton',0,128,0,5000,0,0,NULL); +INSERT INTO `mob_groups` VALUES (86,2345,54,'Lamia_No19',0,0,2996,9500,9000,0,NULL); +INSERT INTO `mob_groups` VALUES (87,2360,54,'Lamias_Skeleton',0,128,0,4200,0,0,NULL); INSERT INTO `mob_groups` VALUES (88,2417,54,'Lil_Apkallu',0,128,1523,15000,0,0,NULL); INSERT INTO `mob_groups` VALUES (89,4217,54,'Velionis',0,128,2576,15000,0,0,NULL); INSERT INTO `mob_groups` VALUES (90,4490,54,'Zareehkl_the_Jubilant',0,128,2794,75000,0,0,NULL); diff --git a/sql/mob_pools.sql b/sql/mob_pools.sql index e21e1b7fa11..48d0c354b3e 100644 --- a/sql/mob_pools.sql +++ b/sql/mob_pools.sql @@ -520,7 +520,7 @@ INSERT INTO `mob_pools` VALUES (461,'Bloodsucker_NI','Bloodsucker',8,0x000014010 INSERT INTO `mob_pools` VALUES (462,'Bloodtear_Baldurf','Bloodtear_Baldurf',108,0x0000580100000000000000000000000000000000,1,1,7,240,100,0,1,0,0,2,0,32,0,159,0,0,0,0,0,208,208,3,58); INSERT INTO `mob_pools` VALUES (463,'Bloodthirster_Madkix','Bloodthirster_Madkix',126,0x0000FC0100000000000000000000000000000000,1,1,5,240,100,0,1,0,1,2,0,32,0,159,0,0,0,0,0,133,133,3,16); INSERT INTO `mob_pools` VALUES (464,'Bloodwing_Impaler','Bloodwing_Impaler',139,0x00006C0200000000000000000000000000000000,14,14,8,240,100,0,1,0,1,0,0,0,27,129,0,0,0,0,0,334,334,0,12); -INSERT INTO `mob_pools` VALUES (465,'Bloody_Bones','Bloody_Bones',416,0x0000DE0600000000000000000000000000000000,8,8,3,240,100,0,1,0,0,2,0,0,0,3,0,0,5,0,0,88,88,2,13); +INSERT INTO `mob_pools` VALUES (465,'Bloody_Bones','Bloody_Bones',416,0x0000DE0600000000000000000000000000000000,8,8,3,290,100,0,1,0,0,2,0,0,0,3,0,0,1,0,0,88,88,2,13); INSERT INTO `mob_pools` VALUES (466,'Bloody_Coffin','Bloody_Coffin',25,0x0000650100000000000000000000000000000000,5,5,3,240,100,0,0,0,0,2,0,0,1828,135,0,0,555,0,0,76,76,3,19); INSERT INTO `mob_pools` VALUES (467,'Bloody_Daggers','Bloody_Daggers',476,0x0000C50100000000000000000000000000000000,6,6,2,240,100,0,1,1,0,2,0,0,1,131,0,0,0,0,0,11,11,1,20); INSERT INTO `mob_pools` VALUES (468,'Bloody_Vrukwuk','Bloody_Vrukwuk',139,0x0000F10300000000000000000000000000000000,7,7,2,240,100,0,1,0,1,0,0,0,0,3,0,0,4,0,0,334,334,1,15); @@ -1562,7 +1562,7 @@ INSERT INTO `mob_pools` VALUES (1503,'Gerwitzs_Soul','Gerwitzs_Soul',408,0x00007 INSERT INTO `mob_pools` VALUES (1504,'Gerwitzs_Sword','Gerwitzs_Sword',62,0x0000C70100000000000000000000000000000000,8,5,4,240,100,0,1,0,0,2,0,32,7,667,16,0,3,0,0,110,110,1,20); INSERT INTO `mob_pools` VALUES (1505,'Gespenst','Gespenst',408,0x0000700100000000000000000000000000000000,1,4,12,240,100,0,1,0,0,0,0,0,0,133,16,0,28,0,0,121,121,1,8); INSERT INTO `mob_pools` VALUES (1506,'Gessho','Gessho',168,0x00003B0400000000000000000000000000000000,13,13,2,240,100,0,1,1,0,50,0,32,7,155,0,0,7,0,0,777,360,1,15); -INSERT INTO `mob_pools` VALUES (1507,'Geush_Urvan','Geush_Urvan',88,0x00004D0500000000000000000000000000000000,4,2,12,360,100,0,1,0,1,2,0,0,0,3,0,0,2,0,0,424,57,3,16); +INSERT INTO `mob_pools` VALUES (1507,'Geush_Urvan','Geush_Urvan',88,0x00004D0500000000000000000000000000000000,4,2,12,360,100,0,1,0,1,2,0,0,0,3,0,0,1,0,0,424,57,3,16); INSERT INTO `mob_pools` VALUES (1508,'Geyser_Lizard','Geyser_Lizard',307,0x0000480100000000000000000000000000000000,1,1,7,240,100,0,1,0,1,2,0,0,290,135,0,0,0,0,0,174,174,3,22); INSERT INTO `mob_pools` VALUES (1509,'GeDha_Evileye','GeDha_Evileye',150,0x00009C0200000000000000000000000000000000,3,3,3,240,100,0,1,0,1,2,0,32,0,155,0,0,20,0,0,202,202,1,15); INSERT INTO `mob_pools` VALUES (1510,'Ghahnis','Ghahnis',293,0x0500610700000000000000000000000000000000,1,1,8,240,100,0,0,0,0,0,0,0,1,155,0,0,0,0,0,145,145,1,17); @@ -2400,7 +2400,7 @@ INSERT INTO `mob_pools` VALUES (2341,'Lamia_No14','Lamia_No14',129,0x06007906000 INSERT INTO `mob_pools` VALUES (2342,'Lamia_No15','Lamia_No15',129,0x0600770600000000000000000000000000000000,17,17,5,240,100,0,1,1,1,0,0,32,0,541,12,0,0,0,0,171,171,2,13); INSERT INTO `mob_pools` VALUES (2343,'Lamia_No17','Lamia_No17',129,0x06006D0600000000000000000000000000000000,5,5,4,240,100,0,1,0,1,0,0,0,0,0,0,0,3,0,0,171,171,1,12); INSERT INTO `mob_pools` VALUES (2344,'Lamia_No18','Lamia_No18',129,0x0600770600000000000000000000000000000000,17,17,5,240,100,0,1,1,1,0,0,0,0,0,0,0,0,0,0,171,171,NULL,NULL); -INSERT INTO `mob_pools` VALUES (2345,'Lamia_No19','Lamia_No19',129,0x0600760600000000000000000000000000000000,4,4,5,240,100,0,1,1,1,2,0,32,0,539,12,0,28,0,0,171,171,1,12); +INSERT INTO `mob_pools` VALUES (2345,'Lamia_No19','Lamia_No19',129,0x0600760600000000000000000000000000000000,4,4,5,270,100,0,1,1,1,2,0,32,0,539,12,0,1,0,0,171,171,1,12); INSERT INTO `mob_pools` VALUES (2346,'Lamia_No2','Lamia_No2',129,0x06006F0600000000000000000000000000000000,11,11,5,240,100,0,1,1,1,0,0,32,0,525,12,0,0,0,0,171,171,2,13); INSERT INTO `mob_pools` VALUES (2347,'Lamia_No21','Lamia_No21',129,0x0600760600000000000000000000000000000000,4,4,5,240,100,0,1,1,1,0,0,32,0,541,12,0,28,0,0,171,171,2,13); INSERT INTO `mob_pools` VALUES (2348,'Lamia_No24','Lamia_No24',129,0x0600750600000000000000000000000000000000,4,4,5,240,100,0,1,1,1,0,0,0,0,0,0,0,28,0,0,171,171,NULL,NULL); @@ -2415,7 +2415,7 @@ INSERT INTO `mob_pools` VALUES (2356,'Lamia_Rover','Lamia_Rover',129,0x060077060 INSERT INTO `mob_pools` VALUES (2357,'Lamia_Sharper','Lamia_Sharper',129,0x0600770600000000000000000000000000000000,17,17,5,240,100,0,1,0,1,0,0,0,0,3,0,0,0,0,0,171,171,NULL,NULL); INSERT INTO `mob_pools` VALUES (2358,'Lamias_Avatar','Lamias_Avatar',243,0x0000170300000000000000000000000000000000,4,4,7,240,100,0,0,0,1,0,0,0,0,129,0,0,0,0,0,34,34,1,30); INSERT INTO `mob_pools` VALUES (2359,'Lamias_Elemental','Lamias_Elemental',259,0x00000F0000000000000000000000000000000000,8,8,11,240,100,0,0,0,1,0,0,0,0,129,16,0,5,0,0,100,100,NULL,NULL); -INSERT INTO `mob_pools` VALUES (2360,'Lamias_Skeleton','Lamias_Skeleton',419,0x0000DE0600000000000000000000000000000000,1,1,5,240,100,0,1,0,1,0,0,0,0,0,0,0,0,0,0,227,227,NULL,NULL); +INSERT INTO `mob_pools` VALUES (2360,'Lamias_Skeleton','Lamias_Skeleton',419,0x0000DE0600000000000000000000000000000000,1,1,5,240,100,0,1,0,1,0,0,0,0,0,0,0,0,0,0,227,227,0,10); INSERT INTO `mob_pools` VALUES (2361,'Lamia_Toxophilite_AR','Lamia_Toxophilite',129,0x0600710600000000000000000000000000000000,11,11,5,240,100,0,1,0,1,0,0,0,344,517,12,0,0,0,0,171,171,2,13); INSERT INTO `mob_pools` VALUES (2362,'Lamie_Bellydancer','Lamie_Bellydancer',129,0x0600750600000000000000000000000000000000,15,15,4,240,100,0,1,0,1,0,0,0,137,517,0,0,0,0,0,171,171,2,13); INSERT INTO `mob_pools` VALUES (2363,'Lamie_Deathdancer','Lamie_Deathdancer',129,0x0600780600000000000000000000000000000000,17,17,5,240,100,0,1,0,1,0,0,0,185,517,0,0,0,0,0,171,171,2,13); @@ -4559,7 +4559,7 @@ INSERT INTO `mob_pools` VALUES (4499,'ZeVho_Fallsplitter','ZeVho_Fallsplitter',1 INSERT INTO `mob_pools` VALUES (4500,'Zhadjaraf','Zhadjaraf',293,0x0500610700000000000000000000000000000000,1,1,8,240,100,0,0,0,0,0,0,0,1,155,0,0,0,0,0,145,145,1,17); INSERT INTO `mob_pools` VALUES (4501,'Zhayolm_Apkallu','Zhayolm_Apkallu',171,0x0000BB0600000000000000000000000000000000,2,2,1,480,100,0,0,0,1,0,0,0,298,131,5,0,0,0,0,27,27,1,8); INSERT INTO `mob_pools` VALUES (4502,'Zhuu_Buxu_the_Silent','Zhuu_Buxu_the_Silent',168,0x00004C0200000000000000000000000000000000,13,13,2,240,100,0,1,0,1,2,0,32,0,155,0,0,7,0,0,360,360,1,15); -INSERT INTO `mob_pools` VALUES (4503,'Zikko','Zikko',212,0x0000BE0600000000000000000000000000000000,4,4,7,240,100,0,1,1,1,2,0,32,0,157,4,0,2,0,0,166,165,2,13); +INSERT INTO `mob_pools` VALUES (4503,'Zikko','Zikko',212,0x0000BE0600000000000000000000000000000000,4,4,7,240,100,0,1,1,1,2,0,32,0,157,4,0,1,0,0,166,165,2,13); INSERT INTO `mob_pools` VALUES (4504,'Zipacna','Zipacna',63,0x0000B00100000000000000000000000000000000,1,1,11,320,100,0,1,0,0,2,0,0,20,129,0,0,0,0,0,135,135,0,17); INSERT INTO `mob_pools` VALUES (4505,'Ziphius','Ziphius',38,0x00005C0100000000000000000000000000000000,1,1,7,240,100,0,0,0,0,2,0,32,5580,153,0,0,0,0,0,197,197,1,27); INSERT INTO `mob_pools` VALUES (4506,'Zircon_Quadav','Zircon_Quadav',150,0x0000950200000000000000000000000000000000,4,4,5,265,100,0,1,0,1,0,0,0,126,131,0,0,2,0,0,202,202,1,15); diff --git a/sql/mob_skill_lists.sql b/sql/mob_skill_lists.sql index 9319a380481..fb8bfa64e4c 100644 --- a/sql/mob_skill_lists.sql +++ b/sql/mob_skill_lists.sql @@ -364,8 +364,14 @@ INSERT INTO `mob_skill_lists` VALUES ('Dragon',87,648); -- Petro Eyes INSERT INTO `mob_skill_lists` VALUES ('Dragon',87,649); -- Voidsong INSERT INTO `mob_skill_lists` VALUES ('Dragon',87,650); -- Thornsong INSERT INTO `mob_skill_lists` VALUES ('Dragon',87,651); -- Lodesong --- 88: Bloody Bones --- 89: Draugar +INSERT INTO `mob_skill_lists` VALUES ('Bloody_Bones',88,479); -- Horror Cloud +INSERT INTO `mob_skill_lists` VALUES ('Bloody_Bones',88,484); -- Black Cloud +INSERT INTO `mob_skill_lists` VALUES ('Bloody_Bones',88,485); -- Blood Saber +INSERT INTO `mob_skill_lists` VALUES ('Bloody_Bones',88,1795); -- Malediction +INSERT INTO `mob_skill_lists` VALUES ('Bloody_Bones',89,479); -- Horror Cloud +INSERT INTO `mob_skill_lists` VALUES ('Bloody_Bones',89,484); -- Black Cloud +INSERT INTO `mob_skill_lists` VALUES ('Bloody_Bones',89,485); -- Blood Saber +INSERT INTO `mob_skill_lists` VALUES ('Bloody_Bones',89,1795); -- Malediction INSERT INTO `mob_skill_lists` VALUES ('Dvergr',90,2113); INSERT INTO `mob_skill_lists` VALUES ('Dvergr',90,2114); INSERT INTO `mob_skill_lists` VALUES ('Dvergr',90,2115); diff --git a/sql/mob_spawn_points.sql b/sql/mob_spawn_points.sql index 71dbac0a6b4..06bde0ceb38 100644 --- a/sql/mob_spawn_points.sql +++ b/sql/mob_spawn_points.sql @@ -13479,7 +13479,7 @@ INSERT INTO `mob_spawn_points` VALUES (16998651,0,'Lahama','Lahama',97,78,80,106 INSERT INTO `mob_spawn_points` VALUES (16998652,0,'Lamia_Deathdancer','Lamia Deathdancer',46,83,83,139.117,-5.489,463.415,137); INSERT INTO `mob_spawn_points` VALUES (16998653,0,'Draugar_Servant','Draugar Servant',42,79,81,136.234,-6.831,468.779,94); INSERT INTO `mob_spawn_points` VALUES (16998654,0,'Draugar_Servant','Draugar Servant',47,79,81,134.976,-7.049,464.915,121); -INSERT INTO `mob_spawn_points` VALUES (16998655,0,'Bloody_Bones','Bloody Bones',48,80,82,136.000,-6.000,476.000,29); +INSERT INTO `mob_spawn_points` VALUES (16998655,0,'Bloody_Bones','Bloody Bones',48,83,83,136.000,-6.000,476.000,29); INSERT INTO `mob_spawn_points` VALUES (16998656,0,'Bhoot','Bhoot',34,80,82,107.258,-2.060,258.006,170); INSERT INTO `mob_spawn_points` VALUES (16998657,0,'Phasma','Phasma',12,73,74,109.564,-4.015,226.246,255); INSERT INTO `mob_spawn_points` VALUES (16998658,0,'Phasma','Phasma',12,73,74,148.004,-7.453,254.834,77); @@ -13696,8 +13696,8 @@ INSERT INTO `mob_spawn_points` VALUES (16998865,0,'Lamia_Exon','Lamia Exon',84,7 INSERT INTO `mob_spawn_points` VALUES (16998866,0,'Lamia_Exon','Lamia Exon',84,76,76,-462.000,-20.500,458.000,7); INSERT INTO `mob_spawn_points` VALUES (16998867,0,'Ornery_Orobon','Ornery Orobon',85,75,80,0.000,0.000,0.000,0); INSERT INTO `mob_spawn_points` VALUES (16998868,0,'Lamia_No19','Lamia No.19',86,78,78,-138.000,-7.600,132.000,161); -INSERT INTO `mob_spawn_points` VALUES (16998869,0,'Lamias_Skeleton','Lamia\'s Skeleton',87,70,70,-136.700,-7.900,132.000,254); -INSERT INTO `mob_spawn_points` VALUES (16998870,0,'Lamias_Skeleton','Lamia\'s Skeleton',87,70,70,-140.000,-7.600,131.000,254); +INSERT INTO `mob_spawn_points` VALUES (16998869,0,'Lamias_Skeleton','Lamia\'s Skeleton',87,75,75,-136.700,-7.900,132.000,254); +INSERT INTO `mob_spawn_points` VALUES (16998870,0,'Lamias_Skeleton','Lamia\'s Skeleton',87,75,75,-140.000,-7.600,131.000,254); INSERT INTO `mob_spawn_points` VALUES (16998871,0,'Lil_Apkallu','Lil\' Apkallu',88,82,83,489.740,-2.742,168.490,190); INSERT INTO `mob_spawn_points` VALUES (16998872,0,'Velionis','Velionis',89,78,80,313.170,-4.089,26.211,247); INSERT INTO `mob_spawn_points` VALUES (16998873,0,'Zareehkl_the_Jubilant','Zareehkl the Jubilant',90,85,86,177.640,-5.159,181.399,135);