Drop Chance

MetaMan

Heir
Customer
QA Engineer
It's a script that changes all the drop rates for the mobs without the player needing to calculate the math.
this example:
CSS:
<group chance="11.718">
        <reward item_id="271" min="1" max="1" chance="0.3507"/>
        <reward item_id="1799" min="1" max="1" chance="46.8938"/>
        <reward item_id="1866" min="1" max="1" chance="21.1025"/>
        <reward item_id="1871" min="1" max="1" chance="31.653"/>
      </group>

The structure group contains a series of drop chances for different items. The group chance represents the overall probability that any of the items within the group will drop. Let's break it down:

  • The group chance is 11.718%. This is the overall probability that an item from this group will drop.
  • Each reward represents a specific item with its own drop chance:
    • Item 271: Drop chance 0.3507%.
    • Item 1799: Drop chance 46.8938%.
    • Item 1866: Drop chance 21.1025%.
    • Item 1871: Drop chance 31.653%.
The total drop chance for these items (if we were to sum them up) should theoretically reach 100%, but since the group chance is smaller (11.718%), it means there's an 11.718% chance that any of these items will drop when a drop event occurs. Within this percentage, the individual item chances determine which specific item will drop.

Let's make it more detailed the actual drop rate:

To calculate the actual drop rate for item 271, we need to consider both the group chance and the individual item chance. The group chance is 11.718%, and within this group, the drop rate for item 271 is 0.3507%.

To find the final drop rate, we multiply the group chance by the item chance:

0.11718×0.003507=0.000411226860.11718 \times 0.003507 = 0.00041122686
So, the final drop rate for item 271 is approximately 0.0411%, which is just over 0.04%.


So, if you set group chance="100", the item drop rates will be as follows:


  • Item 271: 0.3507%
  • Item 1799: 46.8938%
  • Item 1866: 21.1025%
  • Item 1871: 31.653%
This way, the individual percentages are not affected.

In essence, it will perform all the calculations and change them to the actual drop rates.

Here is the group with the actual drop rates calculated:


CSS:
<group chance="100">
    <reward item_id="271" min="1" max="1" chance="0.0410"/>
    <reward item_id="1799" min="1" max="1" chance="5.4939"/>
    <reward item_id="1866" min="1" max="1" chance="2.4732"/>
    <reward item_id="1871" min="1" max="1" chance="3.7080"/>
</group>

Anyone who doesn't understand can simply try a file and they will understand.

Attention: Add the NPCs that have drops.
 

Attachments

В программе которую вы написали, указываться шанс для групп и оно меняет их ?
А как быть если на сервере ставишь рейт х5 и всё количиство дропа увиличиваеться в 5 раз ?
 
Вот бы кол. дропа подредактировать корректно под рейт дропа...
It's a script that changes all the drop rates for the mobs without the player needing to calculate the math.
this example:
CSS:
<group chance="11.718">
        <reward item_id="271" min="1" max="1" chance="0.3507"/>
        <reward item_id="1799" min="1" max="1" chance="46.8938"/>
        <reward item_id="1866" min="1" max="1" chance="21.1025"/>
        <reward item_id="1871" min="1" max="1" chance="31.653"/>
      </group>

The structure group contains a series of drop chances for different items. The group chance represents the overall probability that any of the items within the group will drop. Let's break it down:

  • The group chance is 11.718%. This is the overall probability that an item from this group will drop.
  • Each reward represents a specific item with its own drop chance:
    • Item 271: Drop chance 0.3507%.
    • Item 1799: Drop chance 46.8938%.
    • Item 1866: Drop chance 21.1025%.
    • Item 1871: Drop chance 31.653%.
The total drop chance for these items (if we were to sum them up) should theoretically reach 100%, but since the group chance is smaller (11.718%), it means there's an 11.718% chance that any of these items will drop when a drop event occurs. Within this percentage, the individual item chances determine which specific item will drop.

Let's make it more detailed the actual drop rate:

To calculate the actual drop rate for item 271, we need to consider both the group chance and the individual item chance. The group chance is 11.718%, and within this group, the drop rate for item 271 is 0.3507%.

To find the final drop rate, we multiply the group chance by the item chance:

0.11718×0.003507=0.000411226860.11718 \times 0.003507 = 0.00041122686
So, the final drop rate for item 271 is approximately 0.0411%, which is just over 0.04%.


So, if you set group chance="100", the item drop rates will be as follows:


  • Item 271: 0.3507%
  • Item 1799: 46.8938%
  • Item 1866: 21.1025%
  • Item 1871: 31.653%
This way, the individual percentages are not affected.

In essence, it will perform all the calculations and change them to the actual drop rates.

Here is the group with the actual drop rates calculated:


CSS:
<group chance="100">
    <reward item_id="271" min="1" max="1" chance="0.0410"/>
    <reward item_id="1799" min="1" max="1" chance="5.4939"/>
    <reward item_id="1866" min="1" max="1" chance="2.4732"/>
    <reward item_id="1871" min="1" max="1" chance="3.7080"/>
</group>

Anyone who doesn't understand can simply try a file and they will understand.

Attention: Add the NPCs that have drops.
Вот бы кол. дропа отредактировать коректно под рейт который нужен игроку.
 
Good morning!
Please test it and you will understand by yourself. It doesn't matter what percentage you have set in the server's config, it is exactly the same as before.
The only difference is that this way, the player won't need to do math to understand what the final drop rate of an item is when they press shift click.
 
group.set('chance', '100') and
all problems solved :D
ironically ofc


P.s.: tune it because now it is also changing the adena drop chance making it 100%
either exclude adenas or change this so it also converts the adena chance.

Diff:
@@ -11,8 +11,8 @@
for reward in rewards:
        item_id = reward.get('item_id')
-        if item_id == "57":
-            adjusted_rewards.append(reward)
-        else:
-            adjusted_chance = float(reward.get('chance')) * (float(group_chance) / 100)

+        if adjusted_chance := float(reward.get('chance')) * (float(group_chance) / 100):
 
Last edited:
To adjust the chances for the specific item ID after processing the files, you can add some additional logic at the end of your process_file function.
Specifically, you need to look for the <reward> elements with item_id="57" and then modify their chance attribute.



If I'm not mistaken the drop chance of adena in global npcs is 70%.

Update:
CSS:
import tkinter as tk
from tkinter import messagebox
import os
import xml.etree.ElementTree as ET
import xml.dom.minidom as minidom

def adjust_rewards(group_chance, rewards):
    adjusted_rewards = []
    for reward in rewards:
        item_id = reward.get('item_id')
        if item_id == "57":
            adjusted_rewards.append(reward)
        else:
            adjusted_chance = float(reward.get('chance')) * (float(group_chance) / 100)
            adjusted_rewards.append(ET.Element("reward", {
                'item_id': item_id,
                'min': reward.get('min'),
                'max': reward.get('max'),
                'chance': f'{adjusted_chance:.4f}'
            }))
    return adjusted_rewards

def process_file(input_file, output_file):
    parser = ET.XMLParser(target=ET.TreeBuilder(insert_comments=True))
    tree = ET.parse(input_file, parser=parser)
    root = tree.getroot()

    for rewardlist in root.findall('.//rewardlist'):
        if rewardlist.get('type') != 'NOT_RATED_GROUPED':
            for group in rewardlist.findall('.//group'):
                group_chance = group.get('chance')
                rewards = group.findall('reward')

                adjusted_rewards = adjust_rewards(group_chance, rewards)

                for reward in rewards:
                    group.remove(reward)

                for adj_reward in adjusted_rewards:
                    group.append(adj_reward)

                group.set('chance', '100')

    # Set chance to 70.0 for item_id="57"
    for reward in root.findall('.//reward[@item_id="57"]'):
        reward.set('chance', '70.0')

    xmlstr = minidom.parseString(ET.tostring(root)).toprettyxml(indent="   ")
    xmlstr_no_blank_lines = "\n".join([line for line in xmlstr.split("\n") if line.strip()])

    with open(output_file, "w", encoding='utf-8') as f:
        f.write(f'<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE list SYSTEM "npc.dtd">\n')
        f.write(xmlstr_no_blank_lines.split("<?xml version=\"1.0\" ?>")[1])

def process_all_files(input_folder, output_folder):
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
   
    for filename in os.listdir(input_folder):
        if filename.endswith(".xml"):
            input_file = os.path.join(input_folder, filename)
            output_file = os.path.join(output_folder, filename)
            process_file(input_file, output_file)

def ask_question():
    response = messagebox.askyesno("Question", "Do you love MetaMan?")
    if not response:
        exit()

if __name__ == "__main__":
    root = tk.Tk()
    root.withdraw()
    ask_question()

    input_folder = 'npc'
    output_folder = 'npc_new'
    process_all_files(input_folder, output_folder)

With this code when it completes the process it will do one more task which will be to change the drop chance on adena to 70%.
 
Last edited:
Back
Top