From 256d6fd5f24d63ab33186f14d168803202f1620d Mon Sep 17 00:00:00 2001 From: Skold <113406182+Skold177@users.noreply.github.com> Date: Thu, 9 Apr 2026 21:49:17 -0400 Subject: [PATCH] [lua] [sql] Ouryu Cometh Implements the battlefield Ouryu Cometh --- documentation/known_monsters_animations.txt | 4 +- .../{ochre_blast.lua => ocher_blast.lua} | 2 +- ...chre_blast_alt.lua => ocher_blast_alt.lua} | 2 +- .../Riverne_Site_A01/ouryu_cometh.lua | 12 +- scripts/enum/mob_skill.lua | 10 + scripts/items/mistmelt.lua | 5 +- scripts/zones/Riverne-Site_A01/IDs.lua | 2 +- .../Riverne-Site_A01/mobs/Earth_Elemental.lua | 21 +- scripts/zones/Riverne-Site_A01/mobs/Ouryu.lua | 244 ++++++++++-------- .../Riverne-Site_A01/mobs/Water_Elemental.lua | 21 +- scripts/zones/Riverne-Site_A01/mobs/Ziryu.lua | 105 ++++---- sql/mob_groups.sql | 6 +- sql/mob_skill_lists.sql | 2 +- sql/mob_skills.sql | 22 +- sql/mob_spawn_points.sql | 4 +- 15 files changed, 246 insertions(+), 216 deletions(-) rename scripts/actions/mobskills/{ochre_blast.lua => ocher_blast.lua} (98%) rename scripts/actions/mobskills/{ochre_blast_alt.lua => ocher_blast_alt.lua} (98%) diff --git a/documentation/known_monsters_animations.txt b/documentation/known_monsters_animations.txt index 0a3cb4fe5ac..9ae2af9b860 100644 --- a/documentation/known_monsters_animations.txt +++ b/documentation/known_monsters_animations.txt @@ -964,8 +964,8 @@ 963 Sleet Blast alt 964 Sleet Blast 965 Geotic Breath - 966 Ochre Blast alt - 967 Ochre Blast + 966 Ocher Blast alt + 967 Ocher Blast 968 Sable Breath 969 Snowball 970 Snow Cloud diff --git a/scripts/actions/mobskills/ochre_blast.lua b/scripts/actions/mobskills/ocher_blast.lua similarity index 98% rename from scripts/actions/mobskills/ochre_blast.lua rename to scripts/actions/mobskills/ocher_blast.lua index b76ca3013e2..d0d9284da69 100644 --- a/scripts/actions/mobskills/ochre_blast.lua +++ b/scripts/actions/mobskills/ocher_blast.lua @@ -1,5 +1,5 @@ ----------------------------------- --- Ochre Blast +-- Ocher Blast -- Family: Wyrms -- Description: Deals Earth damage to enemies in area of effect. -- Notes: Used only by Ouryu and Cuelebre while flying. diff --git a/scripts/actions/mobskills/ochre_blast_alt.lua b/scripts/actions/mobskills/ocher_blast_alt.lua similarity index 98% rename from scripts/actions/mobskills/ochre_blast_alt.lua rename to scripts/actions/mobskills/ocher_blast_alt.lua index bb5b5d1ba12..d7e2ced8bbc 100644 --- a/scripts/actions/mobskills/ochre_blast_alt.lua +++ b/scripts/actions/mobskills/ocher_blast_alt.lua @@ -1,5 +1,5 @@ ----------------------------------- --- Ochre Blast Alt +-- Ocher Blast Alt -- Family: Wyrms -- Description: Deals Earth damage to a single target -- Notes: Used by Ouryu in place of regular attacks diff --git a/scripts/battlefields/Riverne_Site_A01/ouryu_cometh.lua b/scripts/battlefields/Riverne_Site_A01/ouryu_cometh.lua index 537ef73696c..649c28746b0 100644 --- a/scripts/battlefields/Riverne_Site_A01/ouryu_cometh.lua +++ b/scripts/battlefields/Riverne_Site_A01/ouryu_cometh.lua @@ -32,7 +32,7 @@ local function healCharacter(player) end end --- players on healed on entry to the battlefield +-- Players are healed when entering the battlefield function content:battlefieldEntry(player, battlefield) healCharacter(player) end @@ -41,17 +41,11 @@ content.groups = { { mobs = { 'Ouryu' }, - superlinkGroup = 1, }, { - mobs = { 'Ziryu' }, - superlinkGroup = 1, - spawned = false, - }, - - { - mobs = { 'Water_Elemental', 'Earth_Elemental' }, + mobs = { 'Water_Elemental', 'Earth_Elemental', 'Ziryu' }, + spawned = false, } } diff --git a/scripts/enum/mob_skill.lua b/scripts/enum/mob_skill.lua index 5aa5080251a..743f8590438 100644 --- a/scripts/enum/mob_skill.lua +++ b/scripts/enum/mob_skill.lua @@ -657,6 +657,16 @@ xi.mobSkill = RANGED_ATTACK_TENZEN_2 = 1400, -- Tenzen Bow Low SOUL_ACCRETION = 1401, + OCHER_BLAST_ATTACK_2 = 1405, + TYPHOON_WING_2 = 1406, + SPIKE_FLAIL_7 = 1407, + GEOTIC_BREATH_2 = 1408, + TOUCHDOWN_7 = 1409, + OCHER_BLAST_2 = 1410, + BAI_WING_2 = 1411, + ABSOLUTE_TERROR_7 = 1412, + HORRID_ROAR_7 = 1413, + MARIONETTE_DICE_2 = 1415, MARIONETTE_DICE_3 = 1416, MARIONETTE_DICE_4 = 1417, diff --git a/scripts/items/mistmelt.lua b/scripts/items/mistmelt.lua index 960bf6cdb52..7855a8f2a50 100644 --- a/scripts/items/mistmelt.lua +++ b/scripts/items/mistmelt.lua @@ -8,10 +8,7 @@ local itemObject = {} itemObject.onItemCheck = function(target, item, param, player) local result = 0 - if - target:getBattlefieldID() ~= xi.battlefield.id.SAVAGE or - target:getName() ~= 'Ouryu' - then + if target:getName() ~= 'Ouryu' then result = xi.msg.basic.ITEM_UNABLE_TO_USE elseif target:checkDistance(player) > 10 then result = xi.msg.basic.TOO_FAR_AWAY diff --git a/scripts/zones/Riverne-Site_A01/IDs.lua b/scripts/zones/Riverne-Site_A01/IDs.lua index 28e5882e7a1..ee274c1d4f9 100644 --- a/scripts/zones/Riverne-Site_A01/IDs.lua +++ b/scripts/zones/Riverne-Site_A01/IDs.lua @@ -39,7 +39,7 @@ zones[xi.zone.RIVERNE_SITE_A01] = ARCANE_PHANTASM = GetFirstID('Arcane_Phantasm'), CARMINE_DOBSONFLY_OFFSET = GetFirstID('Carmine_Dobsonfly'), HELIODROMOS_OFFSET = GetFirstID('Heliodromos'), - ZIRYU = GetTableOfIDs('Ziryu'), + OURYU = GetFirstID('Ouryu'), }, npc = { diff --git a/scripts/zones/Riverne-Site_A01/mobs/Earth_Elemental.lua b/scripts/zones/Riverne-Site_A01/mobs/Earth_Elemental.lua index a47b4e176ad..ce772404af6 100644 --- a/scripts/zones/Riverne-Site_A01/mobs/Earth_Elemental.lua +++ b/scripts/zones/Riverne-Site_A01/mobs/Earth_Elemental.lua @@ -6,17 +6,24 @@ ---@type TMobEntity local entity = {} -entity.onMobInitialize = function(mob) +entity.onMobSpawn = function(mob) mob:setMobMod(xi.mobMod.ROAM_DISTANCE, 500) + mob:setMobMod(xi.mobMod.NO_DROPS, 1) + mob:setRoamFlags(xi.roamFlag.NONE) end -entity.onMobSpawn = function(mob) - -- TODO: add building sleep resistance after added to LSB - -- capture shows about 1 second shorter sleep each time -end +entity.onMobSpellChoose = function(mob, target, spellId) + local spellList = + { + [1] = { xi.magic.spell.STONE_IV, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [2] = { xi.magic.spell.STONEGA_III, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [3] = { xi.magic.spell.QUAKE, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [4] = { xi.magic.spell.RASP, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.RASP, 0, 100 }, + [5] = { xi.magic.spell.SLOW, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.SLOW, 3, 100 }, + [6] = { xi.magic.spell.STONESKIN, mob, false, xi.action.type.ENHANCING_FORCE_SELF, xi.effect.STONESKIN, 0, 100 }, + } -entity.onMobDespawn = function(mob) - mob:setRespawnTime(120) + return xi.combat.behavior.chooseAction(mob, target, nil, spellList) end return entity diff --git a/scripts/zones/Riverne-Site_A01/mobs/Ouryu.lua b/scripts/zones/Riverne-Site_A01/mobs/Ouryu.lua index e1c5f8326dc..7a0c44c34d3 100644 --- a/scripts/zones/Riverne-Site_A01/mobs/Ouryu.lua +++ b/scripts/zones/Riverne-Site_A01/mobs/Ouryu.lua @@ -4,75 +4,86 @@ -- Notes: in Ouryu Cometh (Cloud Evoker) -- !pos 184 0 344 30 ----------------------------------- +local ID = zones[xi.zone.RIVERNE_SITE_A01] +----------------------------------- mixins = { require('scripts/mixins/job_special') } ----------------------------------- ---@type TMobEntity local entity = {} -local offsets = { 1, 2, 3, 4 } -local hpToNextPhase = 6000 -local initialPhaseDuration = 120 -local subsequentPhaseDuration = 120 --- TODO: eventually use animationsub 4, 5, 6 below (as indicated by capture) --- once touchdown mobskill and mistmelt support -local initialGroundPhaseAnimationSub = 0 -local allFlightPhaseAnimationSub = 1 -local subsequentGroundPhaseAnimationSub = 2 - -local function setNextPhaseTriggers(mob, phaseDuration) - local battleTime = 0 - if mob:isEngaged() then - battleTime = mob:getBattleTime() - end +----------------------------------- +-- The adds spawn based off this priority list - when it is time to spawn a add, we will try to spawn the highest priority based off what is alive. +----------------------------------- +local addTable = +{ + [1] = ID.mob.OURYU - 2, -- Water Elemental + [2] = ID.mob.OURYU + 1, -- Ziryu + [3] = ID.mob.OURYU + 2, -- Ziryu + [4] = ID.mob.OURYU - 1, -- Earth Elemental + [5] = ID.mob.OURYU + 3, -- Ziryu + [6] = ID.mob.OURYU + 4, -- Ziryu +} - mob:setLocalVar('nextPhaseTime', battleTime + phaseDuration) - mob:setLocalVar('nextPhaseHP', math.max(mob:getHP() - hpToNextPhase, 0)) -end +----------------------------------- +-- Idle (Wings Down) (AnimationSub(0)) +-- Airborne (AnimationSub(1)) +-- Grounded (Wings Up) (AnimationSub(2)) +----------------------------------- -local function fly(mob) - mob:setAnimationSub(allFlightPhaseAnimationSub) +----------------------------------- +-- Enter/Exit Flight Functions +----------------------------------- +local function enterFlight(mob) + mob:setMobSkillAttack(425) mob:addStatusEffect(xi.effect.ALL_MISS, { power = 1, origin = mob, icon = 0 }) - mob:setMobSkillAttack(731) - setNextPhaseTriggers(mob, subsequentPhaseDuration) + mob:setBehavior(bit.band(mob:getBehavior(), bit.bnot(xi.behavior.NO_TURN))) + mob:setAnimationSub(1) end -local function landWithoutTouchdown(mob) - -- if flying - if mob:getAnimationSub() == allFlightPhaseAnimationSub then - -- need to still show the touchdown animation (as per capture) +local function exitFlight(mob) + mob:setMobSkillAttack(0) + mob:useMobAbility(xi.mobSkill.TOUCHDOWN_1) + mob:delStatusEffect(xi.effect.ALL_MISS) + mob:setBehavior(bit.bor(mob:getBehavior(), xi.behavior.NO_TURN)) + mob:setAnimationSub(2) +end + +----------------------------------- +-- Mistmelt Function +----------------------------------- +local function executeMistmelt(mob) + if mob:getAnimationSub() == 1 then + local currentTime = GetSystemTime() + mob:setLocalVar('phaseChangeTime', currentTime + 120) + mob:setLocalVar('phaseChangeHP', mob:getHP() - 6000) mob:injectActionPacket(mob:getID(), 11, 974, 0, 0x18, 0, 0, 0) + mob:setAnimationSub(2) + mob:delStatusEffect(xi.effect.ALL_MISS) + mob:setMobSkillAttack(0) end - mob:setAnimationSub(subsequentGroundPhaseAnimationSub) - mob:delStatusEffect(xi.effect.ALL_MISS) - mob:setMobSkillAttack(0) - setNextPhaseTriggers(mob, subsequentPhaseDuration) - -- always set this no matter how ouryu lands to avoid any issues mob:setLocalVar('mistmeltUsed', 0) end entity.onMobInitialize = function(mob) mob:addImmunity(xi.immunity.SLOW) + mob:addImmunity(xi.immunity.ELEGY) mob:addImmunity(xi.immunity.TERROR) mob:addImmunity(xi.immunity.STUN) mob:addImmunity(xi.immunity.PLAGUE) - mob:addImmunity(xi.immunity.ELEGY) mob:addImmunity(xi.immunity.PETRIFY) end entity.onMobSpawn = function(mob) - -- resetting so it doesn't respawn in flight mode mob:setMobSkillAttack(0) - mob:setSpellList(548) - mob:setAnimationSub(initialGroundPhaseAnimationSub) - mob:delStatusEffect(xi.effect.ALL_MISS) + mob:setAnimationSub(0) -- Level 90 + 2 + 53 = 145 Base Weapon Damage mob:setMod(xi.mod.UDMGRANGE, -5000) mob:setMod(xi.mod.UDMGMAGIC, -5000) mob:setMod(xi.mod.UDMGBREATH, -5000) - mob:setMod(xi.mod.UFASTCAST, 90) - mob:setMod(xi.mod.DOUBLE_ATTACK, 10) + mob:setMod(xi.mod.UFASTCAST, 80) + mob:setMod(xi.mod.DOUBLE_ATTACK, 15) mob:setMod(xi.mod.REFRESH, 200) mob:setMobMod(xi.mobMod.WEAPON_BONUS, 53) mob:setMobMod(xi.mobMod.DETECTION, bit.bor(xi.detects.SIGHT, xi.detects.HEARING)) @@ -82,43 +93,28 @@ entity.onMobSpawn = function(mob) mob:setMobMod(xi.mobMod.ADD_EFFECT, 1) mob:setMobMod(xi.mobMod.NO_STANDBACK, 1) - -- can use invincible on ground or air + mob:setLocalVar('phaseChangeHP', mob:getHP() - 6000) + + ----------------------------------- + -- May use Invincible every 10 minutes starting at 85% HP + ----------------------------------- xi.mix.jobSpecial.config(mob, { specials = { - { id = xi.mobSkill.INVINCIBLE_1, hpp = math.random(50, 85) }, + { id = xi.mobSkill.INVINCIBLE_1, hpp = 85, cooldown = 600 }, }, }) - - -- set on spawn as the first damage can occur already before onMobEngage - setNextPhaseTriggers(mob, initialPhaseDuration) end entity.onMobEngage = function(mob) - -- spawn ziryu and elementals only on mob engage (not at start of BCNM) - local mobId = mob:getID() - for i, offset in ipairs(offsets) do - local pet = GetMobByID(mobId + offset) - if pet and not pet:isSpawned() then - pet:spawn() - end - end - - -- track if already engaged once so can set the the correct phase duration if roams - if mob:getLocalVar('alreadyEngagedOnce') == 0 then - mob:setLocalVar('alreadyEngagedOnce', 1) - end -end - -entity.onMobRoam = function(mob) - -- if already engaged once then keep setting phase triggers - -- since damage can occur even before onMobEngage - if mob:getLocalVar('alreadyEngagedOnce') == 1 then - setNextPhaseTriggers(mob, subsequentPhaseDuration) - end + local currentTime = GetSystemTime() + mob:setLocalVar('phaseChangeTime', currentTime + 120) + mob:setLocalVar('addSpawnTime', currentTime + math.random(20, 30)) end entity.onMobFight = function(mob, target) + local currentTime = GetSystemTime() + local drawInTable = { conditions = @@ -129,68 +125,92 @@ entity.onMobFight = function(mob, target) } utils.drawIn(target, drawInTable) - -- valid conditions for a change if - not xi.combat.behavior.isEntityBusy(mob) and - mob:canUseAbilities() + mob:getAnimationSub() == 1 and + mob:hasStatusEffect(xi.effect.SLEEP_I) then - local nextPhaseTime = mob:getLocalVar('nextPhaseTime') - local nextPhaseHP = mob:getLocalVar('nextPhaseHP') - local mistmeltUsed = mob:getLocalVar('mistmeltUsed') - - if - mob:getBattleTime() > nextPhaseTime or - mob:getHP() < nextPhaseHP - then - -- subanimation 0 is the initial on ground animation, so check if should fly - if mob:getAnimationSub() == initialGroundPhaseAnimationSub then - fly(mob) - -- subanimation 1 is flying animation, so check if should land - elseif mob:getAnimationSub() == allFlightPhaseAnimationSub then - -- use touchdown mobskill - -- touchdown script changes the animation sub, miss status, and mob skill attack - mob:useMobAbility(1302) - -- subanimation 2 is on ground animation, so check if should fly - elseif mob:getAnimationSub() == subsequentGroundPhaseAnimationSub then - fly(mob) - end - -- mistmelt also works on this ouryu - elseif - mistmeltUsed == 1 and - mob:getAnimationSub() == allFlightPhaseAnimationSub - then - landWithoutTouchdown(mob) + mob:wakeUp() + end + + if xi.combat.behavior.isEntityBusy(mob) then + return + end + + if mob:getLocalVar('mistmeltUsed') == 1 then + executeMistmelt(mob) + return + end + + if + currentTime >= mob:getLocalVar('phaseChangeTime') or + mob:getHP() <= mob:getLocalVar('phaseChangeHP') + then + mob:setLocalVar('phaseChangeTime', currentTime + 120) + mob:setLocalVar('phaseChangeHP', mob:getHP() - 6000) + if mob:getAnimationSub() == 1 then + exitFlight(mob) + else + enterFlight(mob) end end - -- Wakeup from sleep immediately if flying - if mob:getAnimationSub() == allFlightPhaseAnimationSub then - mob:wakeUp() + if currentTime >= mob:getLocalVar('addSpawnTime') then + mob:setLocalVar('addSpawnTime', currentTime + math.random(60, 90)) + for i = 1, #addTable do + local addId = addTable[i] + local addToSpawn = GetMobByID(addId) + if addToSpawn and addToSpawn:isDead() then + addToSpawn:spawn() + break + end + end end end -entity.onMobWeaponSkill = function(mob, target, skill, action) - -- only reset change vars if actually perform touchdown mobskill - if skill:getID() == 1302 then - setNextPhaseTriggers(mob, subsequentPhaseDuration) - -- always set this no matter how ouryu lands to avoid any issues - mob:setLocalVar('mistmeltUsed', 0) +entity.onMobMobskillChoose = function(mob, target, skillId) + if skillId == xi.mobSkill.OCHER_BLAST_ATTACK_2 then + return 0 end -end -entity.onMobDespawn = function(mob) - -- if ouryu despawns then also then despawn all ziryu - local mobId = mob:getID() - for i, offset in ipairs(offsets) do - local pet = GetMobByID(mobId + offset) - if pet and pet:isAlive() then - DespawnMob(mobId + offset) - end + local skillList = {} + + -- Mid-flight. + if mob:getAnimationSub() == 1 then + table.insert(skillList, xi.mobSkill.OCHER_BLAST_2) + table.insert(skillList, xi.mobSkill.BAI_WING_2) + + -- Ground. + else + table.insert(skillList, xi.mobSkill.TYPHOON_WING_2) + table.insert(skillList, xi.mobSkill.SPIKE_FLAIL_7) + table.insert(skillList, xi.mobSkill.GEOTIC_BREATH_2) + table.insert(skillList, xi.mobSkill.ABSOLUTE_TERROR_7) + table.insert(skillList, xi.mobSkill.HORRID_ROAR_7) end + + return skillList[math.random(1, #skillList)] +end + +entity.onMobSpellChoose = function(mob, target, spellId) + local spellList = + { + [1] = { xi.magic.spell.STONEGA_III, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [2] = { xi.magic.spell.BREAK, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.PETRIFICATION, 0, 100 }, + [3] = { xi.magic.spell.BREAKGA, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.PETRIFICATION, 0, 100 }, + [4] = { xi.magic.spell.STONESKIN, mob, false, xi.action.type.ENHANCING_FORCE_SELF, xi.effect.STONESKIN, 0, 100 }, + } + + return xi.combat.behavior.chooseAction(mob, target, nil, spellList) end entity.onMobDisengage = function(mob) - landWithoutTouchdown(mob) + if mob:getAnimationSub() == 1 then + mob:injectActionPacket(mob:getID(), 11, 974, 0, 0x18, 0, 0, 0) + mob:delStatusEffect(xi.effect.ALL_MISS) + mob:setBehavior(bit.bor(mob:getBehavior(), xi.behavior.NO_TURN)) + end + + mob:setAnimationSub(0) end entity.onAdditionalEffect = function(mob, target, damage) diff --git a/scripts/zones/Riverne-Site_A01/mobs/Water_Elemental.lua b/scripts/zones/Riverne-Site_A01/mobs/Water_Elemental.lua index 5c862bf0e73..12ed360ecfe 100644 --- a/scripts/zones/Riverne-Site_A01/mobs/Water_Elemental.lua +++ b/scripts/zones/Riverne-Site_A01/mobs/Water_Elemental.lua @@ -6,17 +6,24 @@ ---@type TMobEntity local entity = {} -entity.onMobInitialize = function(mob) +entity.onMobSpawn = function(mob) mob:setMobMod(xi.mobMod.ROAM_DISTANCE, 500) + mob:setMobMod(xi.mobMod.NO_DROPS, 1) + mob:setRoamFlags(xi.roamFlag.NONE) end -entity.onMobSpawn = function(mob) - -- TODO: add building sleep resistance after added to LSB - -- capture shows about 1 second shorter sleep each time -end +entity.onMobSpellChoose = function(mob, target, spellId) + local spellList = + { + [1] = { xi.magic.spell.WATER_IV, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [2] = { xi.magic.spell.WATERGA_III, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [3] = { xi.magic.spell.FLOOD, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [4] = { xi.magic.spell.DROWN, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.DROWN, 0, 100 }, + [5] = { xi.magic.spell.POISONGA_II, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.POISON, 0, 100 }, + [6] = { xi.magic.spell.AQUAVEIL, mob, false, xi.action.type.ENHANCING_FORCE_SELF, xi.effect.AQUAVEIL, 0, 100 }, + } -entity.onMobDespawn = function(mob) - mob:setRespawnTime(60) + return xi.combat.behavior.chooseAction(mob, target, nil, spellList) end return entity diff --git a/scripts/zones/Riverne-Site_A01/mobs/Ziryu.lua b/scripts/zones/Riverne-Site_A01/mobs/Ziryu.lua index a9139859207..3b08cf4580d 100644 --- a/scripts/zones/Riverne-Site_A01/mobs/Ziryu.lua +++ b/scripts/zones/Riverne-Site_A01/mobs/Ziryu.lua @@ -3,74 +3,69 @@ -- Mob: Ziryu -- Notes: in Ouryu Cometh ----------------------------------- -local ID = zones[xi.zone.RIVERNE_SITE_A01] ------------------------------------ ---@type TMobEntity local entity = {} -local ziryuOne = -{ - { 46.836, 76.828, -758.276 }, - { 26.248, 76.607, -750.256 }, - { 42.179, 76.290, -752.683 }, - { 26.127, 76.550, -767.194 }, - { 35.687, 76.152, -757.707 }, - { 48.250, 76.524, -766.964 }, - { 50.825, 76.781, -756.612 }, - { 38.753, 76.809, -771.376 }, -} - -local ziryuTwo = -{ - { -5.680, 76.098, -753.375 }, - { -7.673, 76.109, -753.720 }, - { -5.063, 76.632, -769.115 }, - { 5.228, 76.399, -767.280 }, - { 5.263, 76.308, -757.192 }, - { -4.365, 76.112, -750.562 }, - { -0.636, 76.000, -763.672 }, -} - -local ziryuThree = +local spawnPoints = { - { 0.744, 76.462, -712.730 }, - { 3.663, 76.234, -710.823 }, - { 0.834, 76.032, -721.327 }, - { 9.013, 76.413, -722.767 }, - { -2.091, 76.000, -718.037 }, - { 10.238, 76.550, -724.555 }, + { x = -7.673, y = 76.109, z = -753.720 }, + { x = -5.680, y = 76.098, z = -753.375 }, + { x = -5.063, y = 76.632, z = -769.115 }, + { x = -4.365, y = 76.112, z = -750.562 }, + { x = -2.091, y = 76.000, z = -718.037 }, + { x = -0.636, y = 76.000, z = -763.672 }, + { x = 0.744, y = 76.462, z = -712.730 }, + { x = 0.834, y = 76.032, z = -721.327 }, + { x = 3.663, y = 76.234, z = -710.823 }, + { x = 5.228, y = 76.399, z = -767.280 }, + { x = 5.263, y = 76.308, z = -757.192 }, + { x = 9.013, y = 76.413, z = -722.767 }, + { x = 9.715, y = 76.785, z = -744.856 }, + { x = 10.129, y = 65.914, z = -736.797 }, + { x = 10.238, y = 76.550, z = -724.555 }, + { x = 22.027, y = 76.512, z = -730.651 }, + { x = 26.127, y = 76.550, z = -767.194 }, + { x = 26.248, y = 76.607, z = -750.256 }, + { x = 35.687, y = 76.152, z = -757.707 }, + { x = 36.108, y = 76.590, z = -710.141 }, + { x = 38.753, y = 76.809, z = -771.376 }, + { x = 42.179, y = 76.290, z = -752.683 }, + { x = 46.836, y = 76.828, z = -758.276 }, + { x = 48.250, y = 76.524, z = -766.964 }, + { x = 49.704, y = 76.034, z = -722.611 }, + { x = 50.825, y = 76.781, z = -756.612 }, } -local ziryuFour = -{ - { 10.129, 65.914, -736.797 }, - { 9.715, 76.785, -744.856 }, - { 22.027, 76.512, -730.651 }, - { 36.108, 76.590, -710.141 }, - { 49.704, 76.034, -722.611 }, -} +entity.onMobInitialize = function(mob) + local spawnPoint = spawnPoints[math.random(1, #spawnPoints)] + mob:setSpawn(spawnPoint.x, spawnPoint.y, spawnPoint.z) +end entity.onMobSpawn = function(mob) mob:setMobMod(xi.mobMod.CHARMABLE, 1) mob:setMobMod(xi.mobMod.SOUND_RANGE, 30) + mob:setMobMod(xi.mobMod.ROAM_DISTANCE, 500) + mob:setMobMod(xi.mobMod.ROAM_RATE, 10) + mob:setRoamFlags(xi.roamFlag.WORM) end -entity.onMobDespawn = function(mob) - mob:setRespawnTime(120) - local randspawn1 = ziryuOne[math.random((1), (8))] - local randspawn2 = ziryuTwo[math.random((1), (7))] - local randspawn3 = ziryuThree[math.random((1), (6))] - local randspawn4 = ziryuFour[math.random((1), (5))] +entity.onMobSpellChoose = function(mob, target, spellId) + local spellList = + { + [1] = { xi.magic.spell.STONE_IV, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [2] = { xi.magic.spell.STONEGA_III, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [3] = { xi.magic.spell.QUAKE, target, false, xi.action.type.DAMAGE_TARGET, nil, 0, 100 }, + [4] = { xi.magic.spell.RASP, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.RASP, 0, 100 }, + [5] = { xi.magic.spell.BIND, target, false, xi.action.type.ENFEEBLING_TARGET, xi.effect.BIND, 0, 100 }, + [6] = { xi.magic.spell.STONESKIN, mob, false, xi.action.type.ENHANCING_FORCE_SELF, xi.effect.STONESKIN, 0, 100 }, + } - if mob:getID() == ID.mob.ZIRYU[1] then - mob:setSpawn(randspawn1[1], randspawn1[2], randspawn1[3]) - elseif mob:getID() == ID.mob.ZIRYU[2] then - mob:setSpawn(randspawn2[1], randspawn2[2], randspawn2[3]) - elseif mob:getID() == ID.mob.ZIRYU[3] then - mob:setSpawn(randspawn3[1], randspawn3[2], randspawn3[3]) - elseif mob:getID() == ID.mob.ZIRYU[4] then - mob:setSpawn(randspawn4[1], randspawn4[2], randspawn4[3]) - end + return xi.combat.behavior.chooseAction(mob, target, nil, spellList) +end + +entity.onMobDespawn = function(mob) + local spawnPoint = spawnPoints[math.random(1, #spawnPoints)] + mob:setSpawn(spawnPoint.x, spawnPoint.y, spawnPoint.z) end return entity diff --git a/sql/mob_groups.sql b/sql/mob_groups.sql index 81f8a75bb37..633cc7fed97 100644 --- a/sql/mob_groups.sql +++ b/sql/mob_groups.sql @@ -1198,10 +1198,10 @@ INSERT INTO `mob_groups` VALUES (11,1355,30,'Flamedrake',300,0,841,0,0,0,NULL); INSERT INTO `mob_groups` VALUES (12,641,30,'Carmine_Dobsonfly',86400,0,418,1200,0,0,NULL); INSERT INTO `mob_groups` VALUES (13,4532,30,'Darner',300,0,141,0,0,0,'ABYSSEA'); INSERT INTO `mob_groups` VALUES (14,68,30,'Aiatar',0,32,35,5200,0,0,NULL); -INSERT INTO `mob_groups` VALUES (15,4309,30,'Water_Elemental',0,128,2629,1100,0,0,NULL); -INSERT INTO `mob_groups` VALUES (16,1160,30,'Earth_Elemental',0,128,733,1100,0,0,NULL); +INSERT INTO `mob_groups` VALUES (15,4309,30,'Water_Elemental',0,128,2629,3200,0,0,NULL); +INSERT INTO `mob_groups` VALUES (16,1160,30,'Earth_Elemental',0,128,733,3200,0,0,NULL); INSERT INTO `mob_groups` VALUES (17,3070,30,'Ouryu',0,128,1962,50000,0,0,NULL); -INSERT INTO `mob_groups` VALUES (18,4507,30,'Ziryu',0,128,2804,0,0,0,NULL); +INSERT INTO `mob_groups` VALUES (18,4507,30,'Ziryu',0,128,2804,3500,0,0,NULL); INSERT INTO `mob_groups` VALUES (19,215,30,'Arcane_Phantasm',0,128,0,0,0,0,NULL); INSERT INTO `mob_groups` VALUES (20,3596,30,'Shieldtrap',0,128,2235,0,0,0,NULL); INSERT INTO `mob_groups` VALUES (21,7286,30,'Ouryu',0,128,1962,50000,0,0,NULL); diff --git a/sql/mob_skill_lists.sql b/sql/mob_skill_lists.sql index 16a3572683e..44bf2dd9cd9 100644 --- a/sql/mob_skill_lists.sql +++ b/sql/mob_skill_lists.sql @@ -1918,7 +1918,7 @@ INSERT INTO `mob_skill_lists` VALUES ('OrcCaster',423,766); INSERT INTO `mob_skill_lists` VALUES ('Geush_Urvan',424,495); -- Snort INSERT INTO `mob_skill_lists` VALUES ('Geush_Urvan',424,496); -- Rabid Dance INSERT INTO `mob_skill_lists` VALUES ('Geush_Urvan',424,497); -- Lowing --- 425 to 435: free +INSERT INTO `mob_skill_lists` VALUES ('OuryuCometh',425,1405); -- Ouryu Flying Attack INSERT INTO `mob_skill_lists` VALUES ('Bloodlapper',436,2162); INSERT INTO `mob_skill_lists` VALUES ('Ghillie_Dhu',437,685); INSERT INTO `mob_skill_lists` VALUES ('Highlander_Lizard',438,371); diff --git a/sql/mob_skills.sql b/sql/mob_skills.sql index 37e6846909f..a252d6ab0b1 100644 --- a/sql/mob_skills.sql +++ b/sql/mob_skills.sql @@ -1322,12 +1322,12 @@ INSERT INTO `mob_skills` VALUES (1294,658,'gregale_wing_air',1,0.0,30.0,2000,150 INSERT INTO `mob_skills` VALUES (1295,659,'absolute_terror',0,0.0,18.0,4000,1500,4,0,0,0,0,0,0); INSERT INTO `mob_skills` VALUES (1296,660,'horrid_roar_3',0,0.0,18.0,4000,1500,4,0,0,0,0,0,0); -- INSERT INTO `mob_skills` VALUES (1297,1041,'ocher_blast',0,0.0,7.0,2000,1500,4,0,0,0,0,0,0); -INSERT INTO `mob_skills` VALUES (1298,966,'ochre_blast_alt',0,0.0,18.0,2000,0,4,4,0,0,0,0,0); +INSERT INTO `mob_skills` VALUES (1298,966,'ocher_blast_alt',0,0.0,18.0,2000,0,4,4,0,0,0,0,0); INSERT INTO `mob_skills` VALUES (1299,653,'typhoon_wing',1,0.0,30.0,2000,1500,4,0,0,0,0,0,0); INSERT INTO `mob_skills` VALUES (1300,654,'spike_flail',1,0.0,23.0,2000,2000,4,0,0,0,0,0,0); INSERT INTO `mob_skills` VALUES (1301,965,'geotic_breath',4,0.0,18.0,2000,1500,4,0,0,0,0,0,0); INSERT INTO `mob_skills` VALUES (1302,656,'touchdown',1,0.0,30.0,2000,0,4,@SKILLFLAG_ALWAYS_ANIMATE,0,0,0,0,0); -INSERT INTO `mob_skills` VALUES (1303,967,'ochre_blast',1,0.0,23.0,2000,2000,4,0,0,0,0,0,0); +INSERT INTO `mob_skills` VALUES (1303,967,'ocher_blast',1,0.0,23.0,2000,2000,4,0,0,0,0,0,0); INSERT INTO `mob_skills` VALUES (1304,658,'bai_wing',1,0.0,30.0,2000,1500,4,0,0,0,0,0,0); INSERT INTO `mob_skills` VALUES (1305,659,'absolute_terror',1,0.0,18.0,4000,1500,4,0,0,0,0,0,0); INSERT INTO `mob_skills` VALUES (1306,660,'horrid_roar_3',0,0.0,18.0,4000,1500,4,0,0,0,0,0,0); @@ -1429,15 +1429,15 @@ INSERT INTO `mob_skills` VALUES (1401,138,'soul_accretion',0,0.0,7.0,2000,1500,4 -- INSERT INTO `mob_skills` VALUES (1402,1146,'.',0,0.0,7.0,2000,1500,4,0,0,0,0,0,0); -- INSERT INTO `mob_skills` VALUES (1403,1056,'explosive_impulse',0,0.0,7.0,2000,1500,4,0,0,0,0,0,0); -- INSERT INTO `mob_skills` VALUES (1404,1148,'ocher_blast',0,0.0,7.0,2000,1500,4,0,0,0,0,0,0); --- INSERT INTO `mob_skills` VALUES (1405,966,'ocher_blast',0,0.0,7.0,2000,1500,4,0,0,0,0,0,0); --- INSERT INTO `mob_skills` VALUES (1406,653,'typhoon_wing',0,0.0,7.0,2000,1500,4,0,0,0,0,0,0); --- INSERT INTO `mob_skills` VALUES (1407,654,'spike_flail',0,0.0,7.0,2000,1500,4,0,0,0,0,0,0); --- INSERT INTO `mob_skills` VALUES (1408,965,'geotic_breath',0,0.0,7.0,2000,1500,4,0,0,0,0,0,0); --- INSERT INTO `mob_skills` VALUES (1409,656,'touchdown',0,0.0,7.0,2000,1500,2049,0,0,0,0,0,0); --- INSERT INTO `mob_skills` VALUES (1410,967,'ocher_blast',0,0.0,7.0,2000,1500,4,0,0,0,0,0,0); --- INSERT INTO `mob_skills` VALUES (1411,658,'bai_wing',0,0.0,7.0,2000,1500,4,0,0,0,0,0,0); --- INSERT INTO `mob_skills` VALUES (1412,1156,'absolute_terror',0,0.0,7.0,2000,1500,4,0,0,0,0,0,0); --- INSERT INTO `mob_skills` VALUES (1413,660,'horrid_roar',0,0.0,7.0,2000,1500,4,0,0,0,0,0,0); +INSERT INTO `mob_skills` VALUES (1405,966,'ocher_blast_alt',0,0.0,18.0,2000,0,4,4,0,0,0,0,0); +INSERT INTO `mob_skills` VALUES (1406,653,'typhoon_wing',1,0.0,30.0,2000,1500,4,0,0,0,0,0,0); +INSERT INTO `mob_skills` VALUES (1407,654,'spike_flail',1,0.0,25.0,2000,2000,4,0,0,4,0,0,0); +INSERT INTO `mob_skills` VALUES (1408,965,'geotic_breath',2,0.0,18.0,2000,2000,4,0,0,0,0,0,0); +INSERT INTO `mob_skills` VALUES (1409,656,'touchdown',1,0.0,30.0,2000,0,4,@SKILLFLAG_ALWAYS_ANIMATE,0,0,0,0,0); +INSERT INTO `mob_skills` VALUES (1410,967,'ocher_blast',1,0.0,23.0,2000,1500,4,0,0,0,0,0,0); +INSERT INTO `mob_skills` VALUES (1411,658,'bai_wing',1,0.0,30.0,2000,1500,4,0,0,0,0,0,0); +INSERT INTO `mob_skills` VALUES (1412,659,'absolute_terror',1,0.0,18.0,4000,800,4,0,0,0,0,0,0); +INSERT INTO `mob_skills` VALUES (1413,660,'horrid_roar_3',0,0.0,18.0,4000,800,4,0,0,0,0,0,0); -- INSERT INTO `mob_skills` VALUES (1414,1046,'marionette_dice_1',0,0.0,15.0,2000,1500,4,4,0,0,0,0,0); -- Unused INSERT INTO `mob_skills` VALUES (1415,1046,'marionette_dice_2',0,0.0,15.0,2000,1500,4,4,0,0,0,0,0); INSERT INTO `mob_skills` VALUES (1416,1047,'marionette_dice_3',0,0.0,15.0,2000,1500,4,4,0,0,0,0,0); diff --git a/sql/mob_spawn_points.sql b/sql/mob_spawn_points.sql index 28dba42f61d..d0763846a87 100644 --- a/sql/mob_spawn_points.sql +++ b/sql/mob_spawn_points.sql @@ -6177,10 +6177,10 @@ INSERT INTO `mob_spawn_points` VALUES (16900308,0,'Atomic_Cluster','Atomic Clust INSERT INTO `mob_spawn_points` VALUES (16900309,0,'Atomic_Cluster','Atomic Cluster',10,45,48,-61.948,0.385,723.499,255); INSERT INTO `mob_spawn_points` VALUES (16900310,0,'Atomic_Cluster','Atomic Cluster',10,45,48,-71.947,0.316,695.067,112); INSERT INTO `mob_spawn_points` VALUES (16900311,0,'Atomic_Cluster','Atomic Cluster',10,45,48,-61.079,0.213,704.609,133); -INSERT INTO `mob_spawn_points` VALUES (16900312,0,'Water_Elemental','Water Elemental',15,72,73,9.27,75.83,-721.02,0); -INSERT INTO `mob_spawn_points` VALUES (16900313,0,'Earth_Elemental','Earth Elemental',16,72,73,-0.28,76.34,-737.49,41); -- Ouryu Cometh +INSERT INTO `mob_spawn_points` VALUES (16900312,0,'Water_Elemental','Water Elemental',15,72,73,9.27,75.83,-721.02,0); +INSERT INTO `mob_spawn_points` VALUES (16900313,0,'Earth_Elemental','Earth Elemental',16,72,73,-0.28,76.34,-737.49,41); INSERT INTO `mob_spawn_points` VALUES (16900314,0,'Ouryu','Ouryu',21,90,90,18.67,76.18,-740.65,224); INSERT INTO `mob_spawn_points` VALUES (16900315,0,'Ziryu','Ziryu',18,72,74,-8.300,75.828,-757.276,100); INSERT INTO `mob_spawn_points` VALUES (16900316,0,'Ziryu','Ziryu',18,72,74,0.680,76.098,-728.375,143);