Jump to content

[PY]Script to add/alter/remove mob_drop_item.txt - also replaces korean group names


Recommended Posts

  • Premium
import logging
import math
import re
import shutil
from datetime import datetime

from termcolor import colored

logging.basicConfig(level=logging.INFO, format='%(message)s')
logger = logging.getLogger()


def replace_group_names(input_file, output_file):
    with open(input_file, 'r', encoding='utf-8', errors='replace') as file:
        content = file.read()

    # Find all group names, including those with Korean characters and any other content
    group_matches = re.findall(r'Group\t([^\n{]+)', content)

    # Create a mapping of old names to new generic names
    name_map = {name.strip(): f'Group_{i + 1}' for i, name in enumerate(group_matches)}

    # Replace old names with new generic names
    for old_name, new_name in name_map.items():
        content = re.sub(rf'Group\t{re.escape(old_name)}(?=\s*\{{)', f'Group\t{new_name}', content, flags=re.MULTILINE)

    with open(output_file, 'w', encoding='utf-8') as file:
        file.write(content)

    print(f"Processed {len(name_map)} group names.")
    print(f"Modified content written to {output_file}")


def create_backup(file_path):
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    backup_path = f"{file_path}.{timestamp}.bak"
    shutil.copy2(file_path, backup_path)
    logger.info(colored(f"Backup created: {backup_path}", "yellow"))


def find_groups(content):
    pattern = r'Group\s+(\S+)\s*\{(.*?)\}'
    return re.finditer(pattern, content, re.DOTALL)

def modify_mob_items(input_file, output_file, action, item_data=None, allow_duplicates=False):
    with open(input_file, 'r', encoding='utf-8', errors='replace') as file:
        content = file.read()

    groups = find_groups(content)
    remove_all = action == 'remove' and any(m['mob'] == 'all' for item_id in item_data for m in item_data[item_id])

    for group_match in groups:
        group_name = group_match.group(1)
        group_content = group_match.group(2)

        lines = group_content.strip().split('\n')
        header_lines = [line for line in lines if not re.match(r'\s*\d+\s+\d+\s+\d+\s+\d+', line)]
        item_lines = [line for line in lines if re.match(r'\s*\d+\s+\d+\s+\d+\s+\d+', line)]

        modified = False

        if action == 'remove_duplicates':
            # Create a dictionary to store items with their highest chance
            item_chances = {}
            for line in item_lines:
                parts = line.split()
                item_id = parts[1]
                chance = float(parts[3])
                quantity = int(parts[2])
                
                if item_id in item_chances:
                    if chance > item_chances[item_id]['chance']:
                        item_chances[item_id] = {'chance': chance, 'quantity': quantity, 'line': line}
                else:
                    item_chances[item_id] = {'chance': chance, 'quantity': quantity, 'line': line}
            
            # Check if we found any duplicates
            if len(item_chances) < len(item_lines):
                modified = True
                # Keep only the items with highest chances
                item_lines = [item_data['line'] for item_data in item_chances.values()]
                logger.info(colored(
                    f"Group {group_name}: Removed duplicates, keeping highest chances", 
                    "green"
                ))

            if action == 'remove':
                for item_id in item_data:
                    if remove_all or any(m['mob'] == 'all' for m in item_data[item_id]):
                        original_count = len(item_lines)
                        item_lines = [line for line in item_lines if item_id != line.split()[1]]
                        if len(item_lines) < original_count:
                            logger.info(colored(f"Group {group_name}: Removed item {item_id} (all condition)", "green"))
                            modified = True
                    else:
                        mob_match = re.search(r'Mob\s+(\d+)', group_content)
                        if mob_match:
                            mob_id = mob_match.group(1)
                            mob_data = next((m for m in item_data[item_id] if m['mob'] == mob_id), None)
                            if mob_data:
                                original_count = len(item_lines)
                                item_lines = [line for line in item_lines if item_id != line.split()[1]]
                                if len(item_lines) < original_count:
                                    logger.info(
                                        colored(f"Group {group_name}: Removed item {item_id} from mob {mob_id}", "green"))
                                    modified = True

        elif action == 'add':
            mob_match = re.search(r'Mob\s+(\d+)', group_content)
            if mob_match:
                mob_id = mob_match.group(1)
                for item_id in item_data:
                    mob_data = next((m for m in item_data[item_id] if m['mob'] == mob_id or m['mob'] == 'all'), None)
                    if mob_data:
                        # Find the maximum chance in the current group
                        max_chance = max(float(line.split()[-1]) for line in item_lines) if item_lines else 400
                        
                        # Calculate new chance as a percentage of the max chance
                        new_chance = math.ceil((mob_data['chance'] / 100) * max_chance)
                        
                        existing_items = [line for line in item_lines if item_id in line.split()]
                        if existing_items and not allow_duplicates:
                            for existing_item in existing_items:
                                parts = existing_item.split()
                                if mob_data.get('override', True):
                                    parts[2] = str(mob_data['quantity'])
                                else:
                                    parts[2] = str(int(parts[2]) + mob_data['quantity'])
                                parts[3] = str(new_chance)
                                item_lines = [line if line != existing_item else '\t'.join(parts) for line in item_lines]
                            logger.info(colored(
                                f"Group {group_name}: Updated item {item_id} for mob {mob_id}, new quantity: {parts[2]}, new chance: {new_chance}",
                                "green"))
                        else:
                            new_index = len(item_lines) + 1
                            new_item = f"\t{new_index}\t{item_id}\t{mob_data['quantity']}\t{new_chance}"
                            item_lines.append(new_item)
                            logger.info(colored(
                                f"Group {group_name}: Added item {item_id} to mob {mob_id} with index {new_index}, chance {new_chance} (target: {mob_data['chance']}% of {max_chance})",
                                "green"))
                        modified = True
                        
        if modified:
            # Renumber items
            item_lines = [
                f"\t{i + 1}\t" + '\t'.join(line.split()[1:])
                for i, line in enumerate(item_lines)
            ]

            # Reconstruct group content
            new_group_content = '\n'.join(header_lines + item_lines)
            content = content.replace(group_match.group(0), f"Group\t{group_name}\n{{\n{new_group_content}\n}}")

    with open(output_file, 'w', encoding='utf-8') as file:
        file.write(content)

    logger.info(colored(f"Modified content written to {output_file}", "green"))


if __name__ == "__main__":
    input_file = 'mob_drop_item.txt'
    output_file = 'mob_drop_item.txt'

    create_backup(input_file)

    # Replace Korean group names
    # replace_group_names(input_file, output_file)

    # for mob in range(8001, 8010):
        # item_data_50514 = {
            # "50514": [{"mob": str(mob), "chance": 110, "quantity": 1}]
        # }
        # modify_mob_items(output_file, output_file, item_data_50514, 'add')

        # item_data_50515 = {
            # "50515": [{"mob": str(mob), "chance": 17, "quantity": 1}]
        # }
        # modify_mob_items(output_file, output_file, item_data_50515, 'add')

    # # Loop for mobs 8010 to 8027, adding 50514, 50515, and 50525 separately
    # for mob in range(8009, 8028):
        # item_data_50514 = {
            # "50514": [{"mob": str(mob), "chance": 15, "quantity": 1}]
        # }
        # modify_mob_items(output_file, output_file, item_data_50514, 'add')

        # item_data_50515 = {
            # "50515": [{"mob": str(mob), "chance": 17, "quantity": 1}]
        # }
        # modify_mob_items(output_file, output_file, item_data_50515, 'add')

        # item_data_50525 = {
            # "50525": [{"mob": str(mob), "chance": 90, "quantity": 1}]
        # }
        # modify_mob_items(output_file, output_file, item_data_50525, 'add')

    # item_data = {
        # "50525": [{"mob": str(mob), "chance": 0, "quantity": 1}]
    # }
    # modify_mob_items(output_file, output_file, item_data, 'add')


    # To remove items from specific mobs
    # item_data_remove = {"50300": [{"mob": "8007", "chance": 0, "quantity": 0}]}
    # modify_mob_items(input_file, output_file, item_data_remove, 'remove')

    # To remove items from all groups
    # item_data_remove_all = {"50300": [{"mob": "all", "chance": 0, "quantity": 0}]}
    # modify_mob_items(input_file, output_file, item_data_remove_all, 'remove')

    # List of items to remove from all mobs
    items_to_remove = [
        27003, 27005, 27006, 27002, 30022, 30046, 8003,
        376, 396, 1226, 2246, 3266, 5216, 6166, 7346, 21326, 21346, 21366, 21386, 21406, 27621, 27622, 27623, 27624,
        30000, 30001, 30002, 30003, 30004, 30005, 30006, 30007, 30008, 30009, 30010, 30011, 30012, 30013, 30014, 30015,
        30016, 30017, 30018, 30019, 30020, 30021, 30022, 30023, 30024, 30025, 30026, 30027, 30028, 30029, 30030, 30031,
        30032, 30033, 30034, 30035, 30036, 30037, 30038, 30039, 30040, 30041, 30042, 30043, 30044, 30045, 30046, 30047,
        30048, 30049, 30050, 30051, 30052, 30053, 30054, 30055, 30056, 30057, 30058, 30059, 30060, 30061, 30062, 30063,
        30065, 30066, 30067, 30068, 30069, 30070, 30071, 30072, 30073, 30074, 30075, 30076, 30077, 30078, 30079, 30080,
        30081, 30082, 30083, 30084, 30085, 30086, 30087, 30088, 30089, 30090, 30091, 30092, 30101, 30102, 30103, 30104,
        30105, 30106, 30107, 30108, 30109, 30110, 30111, 30112, 30113, 30114, 30115, 30116, 30117, 30118, 30119, 30120,
        30121, 30122, 30123, 30124, 30125, 30126, 30127, 30128, 30129, 30130, 30131, 30132, 30133, 30134, 30135, 30136,
        30137, 30138, 30139, 30140, 30141, 30142, 30143, 30144, 30145, 30146, 30147, 30148, 30149, 30150, 30151, 30152,
        30153, 30154, 30155, 30156, 30157, 30158, 30159, 30160, 30161, 30162, 30163, 30164, 30165, 30166, 30167, 30168,
        30169, 30170, 30171, 30172, 30173, 30174, 30175, 30176, 30177, 30178, 30179, 30180, 30183, 30184, 30185, 30186,
        30187, 30188, 30189, 30190, 30191, 30192, 30193, 30194, 30195, 30196, 30197, 30198, 30199, 30203, 30204, 30205,
        30210, 30211, 30212, 30213, 30214, 30215, 30216, 30217, 30218, 30219, 30220, 30221, 30222, 30223, 30224, 30225,
        30226, 30227, 30228, 30251, 30252, 30253, 30254, 30265, 30266, 30267, 30268, 30269, 30500, 30501, 30502, 30503,
        30504, 30505, 30506, 30507, 30508, 30509, 30510, 30511, 30512, 30513, 30514, 30515, 30516, 30517, 30518, 30519,
        30520, 30521, 30522, 30523, 30524, 30525, 30526, 30527, 30528, 30529, 30530, 30531, 30532, 30533, 30534, 30535,
        30536, 30537, 30538, 30539, 30540, 30541, 30542, 30543, 30544, 30545, 30546, 30547, 30548, 30549, 30550, 30551,
        30552, 30553, 30554, 30555, 30556, 30557, 30558, 30559, 30560, 30561, 30562, 30563, 30564, 30565, 30566, 30567,
        30568, 30569, 30570, 30571, 30572, 30573, 30574, 30575, 30576, 30577, 30578, 30579, 30580, 30581, 30582, 30583,
        30584, 30585, 30586, 30600, 30601, 30602, 30603, 30604, 30605, 30606, 30607, 30608, 30609, 30610, 30611, 30612,
        30613, 30614, 30615, 30616, 30617, 30618, 30619, 30620, 30621, 30622, 30623, 30624, 30625, 30626, 30627, 30628,
        30629, 30630, 30639, 30640, 30641, 30642, 30643, 30644, 30645, 30646, 30647, 30648, 30649, 30650, 30651, 30652,
        30653, 30654, 30655, 30656, 30657, 30658, 30659, 30660, 30661, 30662, 30663, 30664, 30666, 30667, 30668, 31001,
        31002, 31003, 31004, 31006, 31007, 31009, 31010, 31011, 31012, 31013, 31014, 31015, 31016, 31017, 31018, 31019,
        31020, 31021, 31022, 31023, 31024, 31025, 31026, 31027, 31028, 31029, 31030, 31031, 31033, 31034, 31035, 31036,
        31037, 31038, 31039, 31040, 31041, 31042, 31043, 31044, 31045, 31046, 31047, 31048, 31049, 31050, 31051, 31052,
        31053, 31054, 31055, 31056, 31057, 31058, 31059, 31060, 31061, 31062, 31063, 31064, 31065, 31066, 31067, 31068,
        31069, 31070, 31071, 31072, 31074, 31075, 31076, 31077, 31079, 31080, 31081, 31082, 31083, 31084, 31085, 31086,
        31087, 31088, 31089, 31090, 31092, 31093, 31094, 31095, 31101, 31102, 31103, 31108, 31109, 31110, 31111, 31112,
        31113, 31114, 31115, 31117, 31118, 31120, 31121, 31122, 31123, 31124, 31125, 31126, 31127, 31128, 31129, 31130,
        31131, 31132, 31133, 31134, 31135, 31136, 31137, 31138, 31145, 31146, 31147, 31149, 31160, 31161, 31180, 31181,
        31196, 31197, 31198, 31199, 31200, 31201, 31202, 31203, 31204, 31205, 31206, 31207, 31208, 31209, 31210, 31211,
        31212, 31213, 33029, 33030, 33031, 35000, 35001, 39070, 39071, 39072, 39073, 39074, 39075, 39076, 39077, 39078,
        39079, 39080, 39085, 39086, 39087, 39088, 39089, 39090, 39091, 39092, 39093, 39094, 39095, 39096, 39097, 39098,
        39099, 39100, 39101, 39102, 39103, 39104, 39105, 39106, 39107, 39108, 39110, 39111, 39112, 39117, 50116, 50701,
        50702, 50703, 50704, 50705, 50706, 50707, 50708, 50709, 50710, 50711, 50712, 50721, 50722, 50723, 50724, 50725,
        50726, 50727, 50728, 50729, 50730, 50731, 50732, 50733, 50734, 50735, 50736, 50737, 50738, 50739, 50740, 50741,
        50926, 55003, 55004, 55005, 55006, 55007, 56013, 71095, 71122, 71123, 71129, 71130, 71201, 72342, 76029, 100300,
        100400, 100500, 100700, 100701, 30022, 27002, 27003, 27004, 27005, 27006, 27007, 8001, 8002, 8003, 8004, 8005,
        30046, 30045,
    ]

    # modify_mob_items(input_file, output_file, action='remove_duplicates')
        
    # items_to_remove = [50006, 50007, 50008, 50009, 30022, 27100, 27101, 27103, 27104, 27110, 2711]
    # # # Create the item_wdata_remove_all dictionary
    # item_data_remove_all = {str(item): [{"mob": "all", "chance": 0, "quantity": 0}] for item in items_to_remove}

    # # Call the modify_mob_items function
    # modify_mob_items(input_file, output_file, item_data_remove_all, 'remove')

    
    # for mob in range(8019, 8028):
        # item_data_50514 = {
            # "27992": [{"mob": str(mob), "chance": 55, "quantity": 1}]
        # }
        # modify_mob_items(output_file, output_file, item_data_50514, 'add')
        
        # item_data_50514 = {
            # "27993": [{"mob": str(mob), "chance": 55, "quantity": 1}]
        # }
        # modify_mob_items(output_file, output_file, item_data_50514, 'add')
        
        # item_data_50514 = {
            # "27994": [{"mob": str(mob), "chance": 55, "quantity": 1}]
        # }
        # modify_mob_items(output_file, output_file, item_data_50514, 'add')
        
    # 2191 turtle
    # 1304 tiger
    # 1901 fox
    # 6431 Chief Orc
    # 1091	Demon King
    # 1092	Proud Demon King
    # 1093	Death Reaper
    # 2091	Queen Spider
    # 6433	Mighty Ice Witch
    # 6434	General Huashin





    bosses = [2191, 1304, 1901, 1091, 6431, 1092, 1093, 2091, 6433, 6434]
    bosses = [2191]

    for mob in bosses:
        item_data_50514 = {
            "27992": [{"mob": str(mob), "chance": 55, "quantity": 1}]
        }
        modify_mob_items(output_file, output_file, item_data_50514, 'add')
        
        # item_data_50514 = {
            # "27993": [{"mob": str(mob), "chance": 55, "quantity": 1}]
        # }
        # modify_mob_items(output_file, output_file, item_data_50514, 'add')
        
        # item_data_50514 = {
            # "27994": [{"mob": str(mob), "chance": 55, "quantity": 1}]
        # }
        # modify_mob_items(output_file, output_file, item_data_50514, 'add')
        
        



UPDATE:

Now removes group if empty after removing all items from it

Also it can be sefely used directly on bsd, in case japanese char appears just deal with them individually, had one item randomly have a japanese name, did not investigate tho


Update2:

Removes duplicates (all of them), for eg same item 2 dropchances

New logic for chance calculation:
Goes infinite so u can add 200% chance for eg
100% chance is determined by max drop chance present in a group

For eg:
item 1 20
item 2 30

100% drop is 30

And based on that 30 the desired percentage is determined, thus 200% means 60

Will proly add a 400 cap (max drop is 400) but not atm

 

Edited by astroNOT
  • Metin2 Dev 3
  • Love 1
Link to comment
Share on other sites

×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.