UO Sagas: Yet Another Magery Trainer

Created: 8 days ago on 05/29/2025, 08:19:46 PMUpdated: 5 days ago on 06/01/2025, 08:09:46 PM
FileType: No file type provided
Size: 14328
Category: training
Skills: magery
Hotkey: No hotkey provided
Tags: training,training magery

Description: This script automates your magery training in UOSagas.

It will automatically cast spells on your character then heal using bandages.



The script selects spells dynamically based on your Magery skill level,

from Magic Arrow to Flame Strike. It also uses Meditation to recover mana

when it falls below the threshold (10 mana).

Make sure to have plenty of bandages and the required spell reagents

in your backpack. The script runs in an infinite loop, so you can start

it and let it handle the training automatically.

--[[ __ __ ___ ________ ___ _ ___ ___ ____ / / ___ ___ / /____ \\\\---- / _ `/ __/ _ `/ ' \/ _ \/ _ `(_-</ _ \/ _ \/ _ \/ __(_-< ----\ ////---- \_, /_/ \_,_/_/_/_/ .__/\_,_/___/_//_/\___/\___/\__/___/ ----/ /___/ /_/ Magery Trainer v 1.15 Requirements: ------ • Healing/Anatomy (Train at NPC to ~30 is fine) • A few hundred bandages, plenty of reagents (see list below), and a safe place to macro Usage: ------ This script automates your magery training in UO Sagas. It will automatically cast offensive spells on your character, then heal using bandages. If no bandages remain, it will switch to casting “Heal” (and “GreaterHeal” only if Mandrake Root is present), until reagents run out. The script selects offensive spells dynamically based on your Magery skill level, from Magic Arrow to Flamestrike. It also uses Meditation to recover mana when it falls below 10%, and will proactively meditate on cooldown whenever mana is above 50% to maximize Meditation casts. When using magery to heal (Heal/GreaterHeal), it will immediately attempt to cast Meditation if the skill is ready. Added Option: ------------- • AUTO_HEAL (true/false): If false, skip all healing routines (bandage/magery). The script will not heal but also will not cast offensive spells if health ≤ HEALTH_THRESHOLD. Make sure to have plenty of bandages and the required spell reagents in your backpack. The script runs in an infinite loop—press your macro’s stop key to end. Reagents required: --------------------------------- • Magic Arrow: Sulfurous Ash • Fireball: Black Pearl • Lightning: Mandrake Root, Sulfurous Ash • Energy Bolt: Black Pearl, Nightshade • Flamestrike: Spider's Silk, Sulfurous Ash • Heal: Garlic, Ginseng, Spider's Silk • GreaterHeal: Garlic, Ginseng, Spider's Silk, Mandrake Root Note: This script assumes you have enough reagents to sustain casting and that you are in a safe location for training. ]]-- -- === Configuration Constants === local AUTO_HEAL = true -- Set to false if another player will handle healing local GRAPHIC_BANDAGE = 0x0E21 -- Item ID for bandages local DELAY_HEAL = 14000 -- Delay after bandaging or Heal (ms) local DELAY_CAST = 1500 -- Delay after casting offensive spells (ms) local DELAY_LOOP = 1000 -- Delay between loop iterations when idle (ms) local HEALTH_THRESHOLD = 65 -- Heal if health is below or equal to this local MANA_LOW_THRESHOLD = 0.10 -- 10% of MaxMana: threshold to force meditate to full local MANA_MEDIATE_THRESHOLD = 0.50 -- 50% of MaxMana: threshold to proactively meditate -- === Color Constants for Overhead Messages === local COLOR_INFO = 93 -- Blue local COLOR_ALERT = 33 -- Red local COLOR_HINT = 53 -- Yellow -- === Spell Definitions (Offensive) === local SPELLBOOK = { { name = "MagicArrow", skillMin = 0, skillMax = 30, manaCost = 4 }, { name = "Fireball", skillMin = 30, skillMax = 50, manaCost = 9 }, { name = "Lightning", skillMin = 50, skillMax = 70, manaCost = 11 }, { name = "EnergyBolt", skillMin = 70, skillMax = 90, manaCost = 20 }, { name = "Flamestrike", skillMin = 90, skillMax = 100, manaCost = 40 } } -- === Reagent Graphic IDs for Healing Spells === local REAGENT_GARLIC = 0x0F84 -- Garlic local REAGENT_GINSENG = 0x0F85 -- Ginseng local REAGENT_SPIDERSILK = 0x0E1C -- Spider's Silk local REAGENT_MANDRAKE = 0x0F8C -- Mandrake Root -- === Helper Functions === -- Find the first bandage in the player's backpack (strictly inside backpack) local function FindBandage() local item = Items.FindByType(GRAPHIC_BANDAGE) if item and item.RootContainer == Player.Serial then return item end return nil end -- Count how many of a given reagent graphic are in backpack local function CountReagent(graphicID) local items = Items.FindByFilter({ Graphic = graphicID, RootContainer = Player.Serial }) return (#items > 0) and #items or 0 end -- Check if required reagents exist for a given healing spell local function HasReagentsForHeal(spellName) if spellName == "Heal" then return CountReagent(REAGENT_GARLIC) > 0 and CountReagent(REAGENT_GINSENG) > 0 and CountReagent(REAGENT_SPIDERSILK) > 0 elseif spellName == "GreaterHeal" then return CountReagent(REAGENT_GARLIC) > 0 and CountReagent(REAGENT_GINSENG) > 0 and CountReagent(REAGENT_SPIDERSILK) > 0 and CountReagent(REAGENT_MANDRAKE) > 0 end return false end -- Select the appropriate offensive spell based on the player's Magery skill local function SelectOffensiveSpell() local magerySkill = Skills.GetValue("Magery") for _, spell in ipairs(SPELLBOOK) do if magerySkill >= spell.skillMin and magerySkill < spell.skillMax then return spell end end return SPELLBOOK[#SPELLBOOK] end -- Check if the player knows (has) the given spell local function CanCast(spellName) if Spells.CanCast then return Spells.CanCast(spellName) end return true end -- Check if Meditation is ready (no cooldown) local function CanMeditate() if Skills.GetCooldown then local cd = Skills.GetCooldown("Meditation") return (not cd) or (cd <= 0) end return true end -- Attempt to cast Meditation if ready local function TryMeditate() if CanMeditate() and Player.Mana < Player.MaxMana then Messages.Overhead("Casting Meditation to recover mana...", COLOR_INFO, Player.Serial) Skills.Use("Meditation") Pause(100) -- Brief pause to let the skill register end end -- Attempt to cast a healing spell on self -- Returns true if cast was attempted, false if out of reagents or cannot cast local function CastHealSpell() local magerySkill = Skills.GetValue("Magery") local healSpell = nil -- Ensure basic reagents for Heal exist if not (CountReagent(REAGENT_GARLIC) > 0 and CountReagent(REAGENT_GINSENG) > 0 and CountReagent(REAGENT_SPIDERSILK) > 0) then return false end -- Use GreaterHeal if mandrake present, skill ≥ 60, enough mana, and reagents exist if CountReagent(REAGENT_MANDRAKE) > 0 and magerySkill >= 60 and Player.Mana >= 18 and CanCast("GreaterHeal") and HasReagentsForHeal("GreaterHeal") then healSpell = "GreaterHeal" else -- Otherwise, cast normal Heal if possible if Player.Mana >= 6 and CanCast("Heal") and HasReagentsForHeal("Heal") then healSpell = "Heal" else return false -- Cannot cast any heal end end Messages.Overhead("Casting " .. healSpell .. " to heal...", COLOR_INFO, Player.Serial) Spells.Cast(healSpell) -- Wait up to 2 seconds for the targeting cursor, then target player if Targeting.WaitForTarget(2000) then Targeting.Target(Player.Serial) end Pause(DELAY_HEAL) -- Immediately attempt to meditate if Meditation is off cooldown TryMeditate() -- Check Journal for reagent failure if Journal.Contains("You lack the reagents") or Journal.Contains("You do not have enough reagents") then Messages.Overhead("Out of reagents for " .. healSpell .. "! Script stopping.", COLOR_ALERT, Player.Serial) return false end return true end -- Fully meditate until mana is max or player dies local function MeditateToFull() Messages.Overhead("Mana critically low, meditating until full...", COLOR_INFO, Player.Serial) Skills.Use("Meditation") Pause(100) while Player.Mana < Player.MaxMana and not Player.IsDead do Pause(500) end end -- Proactively meditate on cooldown when mana > 50% local function ProactiveMeditate() if Player.Mana > Player.MaxMana * MANA_MEDIATE_THRESHOLD then TryMeditate() end end -- === Main Loop === while true do -- Healing logic if AUTO_HEAL is enabled if AUTO_HEAL and (Player.Poisoned or Player.Hits <= HEALTH_THRESHOLD) then Messages.Overhead("Health low or poisoned, searching for bandages...", COLOR_INFO, Player.Serial) local bandage = FindBandage() if bandage then Messages.Overhead("Bandage found, healing self...", COLOR_HINT, Player.Serial) Player.UseObject(bandage.Serial) if Targeting.WaitForTarget(1000) then Targeting.Target(Player.Serial) end -- After bandage, attempt to meditate if ready TryMeditate() Pause(DELAY_HEAL) else -- No bandage, attempt magery heal Messages.Overhead("No bandages - using Heal/GreaterHeal...", COLOR_ALERT, Player.Serial) if not CastHealSpell() then return -- Stop if no basic heal reagents end end goto continue elseif not AUTO_HEAL and Player.Hits <= HEALTH_THRESHOLD then -- If AUTO_HEAL is disabled and health is too low, do not cast offensive spells Messages.Overhead("Health low but healing disabled!", COLOR_ALERT, Player.Serial) Pause(DELAY_LOOP) goto continue end -- Offensive spellcasting logic local spell = SelectOffensiveSpell() if not Player.Poisoned and Player.Hits > HEALTH_THRESHOLD then if Player.Mana >= spell.manaCost then -- Cast immediately if enough mana Messages.Overhead("Casting " .. spell.name .. " (cost: " .. spell.manaCost .. " mana)...", COLOR_INFO, Player.Serial) Spells.Cast(spell.name) if Targeting.WaitForTarget(2000) then Targeting.Target(Player.Serial) end Pause(DELAY_CAST) -- Do not mediate now; next iteration will handle meditation goto continue elseif Player.Mana < Player.MaxMana * MANA_LOW_THRESHOLD then -- Mana critically low: meditate to full MeditateToFull() goto continue else -- Mana insufficient for chosen spell but above low threshold: proactive meditate if >50% ProactiveMeditate() Pause(DELAY_LOOP) goto continue end else Messages.Overhead("Waiting for health to recover or disabled healing...", COLOR_ALERT, Player.Serial) end -- Idle pause Messages.Overhead("Idle: no action required, looping...", COLOR_INFO, Player.Serial) Pause(DELAY_LOOP) ::continue:: end
View list of scripts
Disclaimer: This is a fan made site and is not directly associated with Ultima Online or UO staff.