TazUO Miningscript

Aus UO-Sigena Wiki
Version vom 19. Oktober 2025, 22:44 Uhr von Bonbori (Diskussion | Beiträge)

(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche

Dieses Script ist für TazUO Legion Scripts (Python). Aktuell sind Routen für die Kohle-, Kupfer und Bronzemine eingetragen, sowie für ein kleines Lehmfeld.

# Important: You need to define a "detect item" graphic
# At least one of this needs to be in your backpack.
# It is used to detect the container ID of your pack animal.
# Said item must only exist directly in your main backpack.
# This is due to odd pack animal container handling on the Sigena freeshard.
# TODO: Count successful minings per tile to avoid "useless mines" to get the empty message
# TODO: max count clay: 3, ore: 9
import API

food_gid = 0x1728
#detect_item_gid = 0xeed # Gold / Kristall
detect_item_gid = 3617 # Bandage
packanimal_gids = [0x0124, 0x0123]
shovel_gid = 0x0f39
tile_marking_hue = 34
active_route = "kohle"
max_tile_yield = 9 # 3 for clay

minable_graphics = list(range(1300, 1400)) + list(range(15830, 15860)) + [3333, 12877, 12878]
ore_gid = 0x19b9
clay_gid = 7145
crystal_gid = 0x2747

mining_messages = {
    "fail" : ["Ihr konntet kein verwertbares Erz gewinnen.", "Ihr findet keinen verwertbaren ", "I am already doing something else."],
    "success": ["Ihr legt etwas ", ],
    "empty": ["Hier gibt es kein Erz mehr abzubauen.", "Hier kann kein sand mehr abgebaut werden.", "Hier ist nichts zu holen.", "ihr eine Spitzhacke.", "Hier kann kein clay mehr abgebaut werden.", "Hier gibt es nichts zu holen."]
}
pack_full_message = "Euer Tier kann ein solches Gewicht nicht tragen."

def main():
    packis = detect_pack_animals()
    move_ore_to_packanimal(packis)
    for waypoint in waypoints[active_route]:
        API.SysMsg(f"Pathfind: {waypoint[0]}, {waypoint[1]}", 33)
        API.Pathfind(x=waypoint[0], y=waypoint[1], z=waypoint[2], distance=0, wait=True, timeout=20)
        for field in get_minable_fields():
            yield_count = 0
            mining_result = -1
            while mining_result != 2 and yield_count < max_tile_yield:
                API.Pause(0.01)
                mining_result = mine(field)
                if API.Player.WeightMax < API.Player.Weight + 10:
                    move_ore_to_packanimal(packis)
                if mining_result == 1:
                    yield_count += 1
                    API.SysMsg(f"Yield: {yield_count}", 33)
                mine_crystal()

            API.MarkTile(field.X, field.Y, tile_marking_hue, API.GetMap())

    move_ore_to_packanimal(packis)

def detect_pack_animals():
    API.Pause(1)
    packis = {}
    animal_serials = get_animal_serials()
    for packi_serial in animal_serials:
        container_id = detect_packi_container_id(packi_serial)
        packis[packi_serial] = {
            "container": container_id,
            "is_full": False
        }
        API.SysMsg(f"Packi: {packi_serial}, Backpack: {container_id}", 33)
    return packis

def detect_packi_container_id(packi_serial) -> int:
    API.UseObject(packi_serial)
    detect_item = API.FindType(detect_item_gid, API.Backpack)
    API.QueueMoveItem(detect_item, packi_serial, 1)
    API.Pause(0.5)
    items = API.FindTypeAll(detect_item_gid)
    for item in items:
        if item.Container != API.Backpack:
            API.QueueMoveItem(item, API.Backpack)
            return item.Container
    return 0

def get_animal_serials():
    animals = []
    mobiles = API.GetAllMobiles()
    if mobiles:
        for mob in mobiles:
            if mob.Graphic in packanimal_gids:
                animals.append(mob.Serial)
                API.SysMsg(f"Found Packi: {mob.Name}", 33)
    return animals

def mine_crystal():
    crystal = API.FindType(graphic=crystal_gid, range=0)
    if crystal:
        API.UseObject(crystal.Serial)
        while not API.InJournal("Ihr legt den Kristall in Euren Rucksack.", clearMatches=True):
            API.Pause(0.1)

def move_ore_to_packanimal(packis):
    API.Msg("all come")
    API.Pause(0.5)
    full_count = 0
    for pack_serial in packis:
        if packis[pack_serial]["is_full"]:
            full_count += 1
            continue
        if full_count >= len(packis):
            raise Exception("All Packis full!")
        items_to_move = []
        ores = API.FindTypeAll(graphic=ore_gid, container=API.Backpack)
        if ores:
            items_to_move += ores
        clay = API.FindTypeAll(graphic=clay_gid, container=API.Backpack)
        if clay:
            items_to_move += clay

        API.UseObject(pack_serial)
        API.Pause(0.1)
        for item in items_to_move:
            API.QueueMoveItem(item.Serial, packis[pack_serial]["container"])
        API.Pause(0.5)
        if API.InJournal(msg=pack_full_message, clearMatches=True):
            packis[pack_serial]["is_full"] = True
    API.Msg("all follow me")


def get_shovel():
    shovels = API.FindTypeAll(graphic=shovel_gid)
    if not shovels:
        raise Exception("No shovel not found")
    result = None
    for shovel_stack in shovels:
        if shovel_stack.Amount == 1:
            return shovel_stack
        result = shovel_stack
    return result


def mine(field) -> int:
    """
    :param x_abs:
    :param y_rel:
    :param z_abs:
    :return: int: 0 = Fail, 1 = Success, 2 = Empty/Ignore
    """
    shovel = get_shovel()
    API.UseObject(shovel.Serial)
    API.WaitForTarget()
    API.Target(field.X, field.Y, field.Z, graphic=field.Graphic)

    while True:
        API.Pause(0.1)
        if API.InJournalAny(msgs=mining_messages["success"], clearMatches=True):
            return 1
        if API.InJournalAny(msgs=mining_messages["fail"], clearMatches=True):
            return 0
        if API.InJournalAny(msgs=mining_messages["empty"], clearMatches=True):
            return 2

def get_minable_fields():
    minable_fields = []
    fields = []
    for x in range(-2, 3):
        for y in range(-2, 3):
            x_abs = x + API.Player.X
            y_abs = y + API.Player.Y
            statics = API.GetStaticsAt(x_abs, y_abs)
            tile = API.GetTile(x_abs, y_abs)
            if statics:
                fields.extend(statics)
            if tile:
                fields.append(tile)

    for field in fields:
        if int(field.Graphic) in minable_graphics and field.Hue != tile_marking_hue:
            minable_fields.append(field)
    return minable_fields

waypoints = {
    "kupfer": [
        [2025, 1304, 0],
        [2020, 1304, 0],
        [2018, 1300, 0],
        [2016, 1297, 0],
        [2011, 1297, 0],
        [2011, 1301, 0],
        [2007, 1301, 0],
        [2007, 1306, 0],
        [2012, 1311, 0],
        [2017, 1306, 0],
        [2020, 1306, 0],
    ],
    "kohle": [
        [5242, 68, -20],
        [5242, 63, -20],
        [5242, 58, -20],
        [5237, 53, -20],
        [5237, 58, -20],
        [5237, 63, -20],
        [5237, 68, -20],
        [5237, 72, -20],
        [5232, 72, -20],
        [5232, 67, -20],
        [5232, 62, -20],
        [5232, 57, -20],
        [5232, 52, -20],
        [5227, 62, -20],
        [5227, 67, -20],
        [5227, 72, -20],
        [5222, 72, -20],
        [5222, 67, -20],
        [5222, 62, -20],
        [5222, 57, -20],
        [5222, 52, -20],
        [5218, 62, -20],
        [5218, 67, -20],
    ],
    "bronze": [
        [1707, 653, 0],
        [1702, 653, 0],
        [1698, 652, 0],
        [1693, 647, 0],
        [1698, 647, 0],
        [1698, 642, 0],
        [1693, 642, 0],
        [1688, 642, 0],
        [1683, 638, 0],
        [1688, 638, 0],
        [1693, 638, 0],
        [1696, 638, 0],
        [1693, 635, 0],
        [1688, 635, 0],
        [1683, 635, 0],
        [1689, 643, 0],# Way down
        [1697, 654, 0],# Way down
        [1699, 658, 0],
        [1703, 658, 0],
        [1703, 663, 0],
        [1699, 663, 0],
        [1699, 668, 0],
        [1703, 668, 0],
        [1704, 672, 0],
        [1699, 672, 0],
        [1706, 675, 0],
        [1696, 675, 0],
        [1691, 675, 0],
        [1691, 680, 0],
        [1688, 680, 0],
        [1696, 680, 0],
        [1701, 680, 0],
        [1706, 680, 0],
        [1706, 684, 0],
        [1701, 684, 0],
        [1696, 684, 0],
        [1691, 684, 0],
        [1691, 687, 0],
        [1696, 689, 0],
        [1701, 689, 0],
    ],
    "clay1": [
        [1164, 1324, 0],
        [1164, 1319, 0],
        [1169, 1319, 0],
        [1169, 1314, 0],
        [1164, 1314, 0],
        [1164, 1309, 0],
        [1169, 1309, 0],
        [1169, 1304, 0],
        [1164, 1304, 0],
        [1164, 1299, 0],
        [1169, 1299, 0],
        [1159, 1304, 0],
        [1159, 1299, 0],
        [1159, 1309, 0],
        [1159, 1314, 0],
        [1159, 1319, 0],
        [1159, 1324, 0],
        [1154, 1324, 0],
        [1154, 1319, 0],
        [1154, 1314, 0],
        [1154, 1309, 0],
        [1154, 1304, 0],
        [1152, 1304, 0],
        [1152, 1309, 0],
    ]
}

main()