UO Unchained: BowcraftFlteching.py (generic craft training possible)

Created: 15 days ago on 05/04/2025, 05:33:50 PMUpdated: 7 days ago on 05/12/2025, 06:19:29 AM
FileType: No file type provided
Size: 6628
Category: Crafting
Skills: Bowcraft/Fletching
Hotkey: No hotkey provided
Tags: training

Description:

Name the script "crafting_trainer.py".

The script is designed to be noob friendly and has been tested on AoS. It may be helpful on UoR, but i havent tried it there. To run the script you need to add the python script to the UO enhanced client. This script is generic and easily converted to train other crafting skills by changing the button IDs in the 'training_plan' variable.

To use the script to train, get a pack animal and set the petName variable to the name of your pack animal. Default pet name is 'craftPet". You also need to have the inventory of the pack animal open.

Buy a stack of 20 to 40 fletching tools. Fill your pack animal with 1550 boards and go to the trash barrel in the lobby of the noobie dungeon. Open the trash barrel and your pack animal's inventory and start the script. You will need to make several trips to where you are keeping your boards, but training in the noob dungeon is the fastest way to gain skill.

In summary:

Buy a stack of 20 to 40 fletching tools

Name pack animal

Fill pack animal with boards

Open trash barrel and pack animal inventory in lobby of noob dungeon

start script

# Razor Enhanced - Generalized Crafting Trainer (Bowcraft example) from AutoComplete import * # ----------------------------- # 🔧 CONFIGURATION (Bowcraft) # ----------------------------- skill_name = "Bowcraft" tool_id = 0x1022 # Fletching Tools material_id = 0x1BD7 # Boards petName = "craftPet" training_plan = [ {"min": 30, "max": 40, "gumps": [15, 9], "junk": [0x1BD4]}, # Shafts {"min": 40, "max": 45, "gumps": [22, 2], "junk": [0x0F3F]}, # Arrows {"min": 45, "max": 50, "gumps": [22, 9], "junk": [0x1BFB]}, # Bolts {"min": 50, "max": 60, "gumps": [29, 2], "junk": [0x13B2]}, # Bow {"min": 60, "max": 70, "gumps": [29, 9], "junk": [0x0F50]}, # Crossbow {"min": 70, "max": 80, "gumps": [29, 23], "junk": [0x26C2]}, # Composite Bow {"min": 80, "max": 100, "gumps": [29, 16], "junk": [0x13FD]}#, # Heavy Crossbow #{"min": 100, "max": 120, "gumps": [29, 37], "junk": [0x26C3]}, # Repeating Crossbow ] # ----------------------------- # Inventory Management # ----------------------------- def get_packy_backpack_serial(): filter = Mobiles.Filter() filter.Name = petName filter.RangeMax = 18 filter.IsHuman = False filter.IsGhost = False packies = Mobiles.ApplyFilter(filter) if not packies or not packies[0].Backpack: Misc.SendMessage("Packy not found or not open!", 33) return None return packies[0].Backpack.Serial def count_items(item_id, container_serial): items = Items.FindAllByID(item_id, -1, container_serial, False, False) return sum(item.Amount for item in items) def move_items_by_type(item_id, source_serial, dest_serial, max_count=100): items = Items.FindAllByID(item_id, -1, source_serial, False, False) moved = 0 for item in items: if moved >= max_count: break amount = min(item.Amount, max_count - moved) Items.Move(item.Serial, dest_serial, amount, 0, 0) moved += amount Misc.Pause(900) def discard_item(item_id, color=-1, container_serial=Player.Backpack.Serial): trash = Misc.ReadSharedValue("trash") if trash is None: Misc.SendMessage("No trash barrel selected!", 33) return items = Items.FindAllByID(item_id, color, container_serial, False, False) for item in items: Items.Move(item.Serial, trash, item.Amount, 0, 0) Misc.Pause(600) def refill_material(threshold=20, max_to_move=100): restock = Misc.ReadSharedValue("restock") if restock is None: Misc.SendMessage("Restock not set!", 33) Misc.ScriptStop("crafting_trainer.py") return if count_items(material_id, restock) == 0: Player.HeadMessage(38, "Packy is empty! Stopping.") Misc.ScriptStop("crafting_trainer.py") return if count_items(material_id, Player.Backpack.Serial) < threshold: move_items_by_type(material_id, restock, Player.Backpack.Serial, max_to_move) Misc.Pause(1000) # ----------------------------- # Tool Use and Crafting # ----------------------------- def use_tool(): tool = Items.FindByID(tool_id, 0x0, Player.Backpack.Serial, False, False) if tool: Items.UseItem(tool) return True return False # ----------------------------- # Junk Cleanup # ----------------------------- def discard_all(junk_ids): for item_id in junk_ids: discard_item(item_id) # ----------------------------- # MAIN SCRIPT # ----------------------------- if not Items.FindByID(tool_id, 0x0, Player.Backpack.Serial, False, False): Player.HeadMessage(38, 'Missing crafting tool!') Misc.ScriptStop("crafting_trainer.py") # Setup: restock + trash barrel restock = get_packy_backpack_serial() if restock is None: Misc.ScriptStop("crafting_trainer.py") Misc.SetSharedValue("restock", restock) if not Misc.CheckSharedValue("trash"): Player.HeadMessage(68, "Select your trash barrel") trash = Target.PromptTarget() Misc.SetSharedValue("trash", trash) # Get current skill level skill = Player.GetSkillValue(skill_name) if skill < 30: Player.HeadMessage(38, f"Train {skill_name} to 30 manually.") Misc.ScriptStop("crafting_trainer.py") # Match to training range for entry in training_plan: if entry["min"] <= skill < entry["max"]: refill_material() if use_tool(): Misc.Pause(1000) Gumps.WaitForGump(0x38920abd, 15000) for gump_id in entry["gumps"]: Gumps.SendAction(0x38920abd, gump_id) Gumps.WaitForGump(0x38920abd, 15000) discard_all(entry["junk"]) break else: Player.HeadMessage(68, f"{skill_name} training complete!") Misc.ScriptStop("crafting_trainer.py") # Handle junk if overweight if Player.MaxWeight - Player.Weight < 20: for item_id in sum([e["junk"] for e in training_plan], []): discard_item(item_id) Misc.Pause(1000)
View list of scripts
Disclaimer: This is a fan made site and is not directly associated with Ultima Online or UO staff.