Jump to content

Калькулятор дропа на фришках Aion


TidalPoo
 Share

Recommended Posts

… или почему комьюнити фришек всегда жалуется и будет жаловаться на дроп.

Итак, если вы заглянули в эту статью, то я думаю вы представляете себе, что такое фришка Aion, эмулятор сервера и так далее.
Так вот, однажды когда мне попался исходный код фришек, я сначала не поверил своим глазам, но перепроверив все открытые исходники, убедился, что так оно и есть, и это кошмар.

Как рассчитывается дроп в оригинальном Aion? У моба/НПЦ, которого игрок пытается убить, есть много гипотетических ящиков с дропом.
1 ящик, это основной дроп для типа моба, там лежат предметы, которые так или иначе выпадут в дроплист с определённым шансом.
2-N – ящиков с различными наборами предметов, с которого может выпасть один, и только один предмет.

Esd1Too2bHg.jpg?size=1024x472&quality=96&sign=ab36a9600a988170eb1a4e64267b34e3&type=album

У каждого предмета есть свой шанс на выпадение. Однако формула расчета тут везде разная.
Для основного дропа, каждый предмет рассчитывается отдельно. Если выражаться условно то в этот ящик закидываются столько удочек, сколько предметов в ящике. Если 4 предмета, то 4 удочки, и тянеееем. Зацепилось что-то вытащили. Таким образом из основного дроп ящика, можно вытащить практически каждый предмет.

Для дополнительных ящиков, работает немного другая система. Берется ящик со всеми в ней предметами, допустим ящик с синими шмотками, перемешивается, после чего туда закидывается удочка, и тянется, если что-то зацепилось, оно выпадет игроку, если нет, то уж извините. Но для каждого доп ящика, удочка кидается одна, и один раз. Шанс вытащить предмет из доп.дропа = сумме шансов для каждого отдельного предмета в ящике. Это значит, что если в ящике 10 предметов с шансом 10, то обязательно выпадет предмет.

Теперь как это работает на фришках. В принципе, это работает почти так же как в оригинале. за исключением того, что:

  • в ящиках лежит всякое гавно. да да да. Там такой хлам лежит дикий, что просто можно мозг сломать.
  • для доп.дропа, система на фришках работает иначе. Из ящика берется случайный предмет, кладется в пустую большую коробку, и закидывается удочка. Допустим – из ящика с синим шмотом, берется случайный предмет, кладется в другой – пустой – ящик, и туда закидывается удочка. Если ничего не зацепилось, то синего шмота не видать. В общем так, для каждого ящика. Размер пустого ящика зависит от процента на предмете. Если процент 10, то ящик в 10 раз больше, если процент 1, то ящик в 100 раз больше.

Разберем код:

1) class NpcDrop

Цикл по каждой группе (ящик предметов) дропа в мобе.

    for (DropGroup dg : this.dropGroup) {
      if (dg.getRace() == Race.PC_ALL || dg.getRace() == race)
        index = dg.dropCalculator(result, index, dropModifier, race, groupMembers); 
    } 

2) class DropGroup
Берем случайный предмет из группы

    if (this.useCategory.booleanValue()) {
      Drop d = this.drop.get(Rnd.get(0, this.drop.size() - 1));
      return d.dropCalculator(result, index, dropModifier, race, groupMembers);
    } 

3) class Drop
По шансу этого предмета, определяем, выдает он или нет.

if (Rnd.get() * 100.0F < percent)

Надеюсь мне удалось объяснить вам как это действует. Попробую показать на картинке, где шанс выбить шмотку будет виден нагляднее.

Калькулятор дропа на фришках Aion., изображение №2

А почему, спросите вы? Потому-что человек, который писал первую версию фришного сервера, был далекий от игровой механики, и до ума не довел. А те кто открывают сервера по сей день, покупают “корявые” сборки у “криворуких” разработчиков. Вот так вот.

Нынешние разработчики не могут сделать систему взвешенного выбора) - random weighted selection

Пример кода для java

public class RandomizeDrop {

    private List<RandomizeEntry> entries = new ArrayList<>();
    private double accumulatedChance;
    private Random rand = new Random();

// Собираем суммированную шкалу

    public void addEntry(int object, float chance) {
        accumulatedChance += chance;
        RandomizeEntry ent = new RandomizeEntry();
        ent.object = object;
        ent.accumulatedWeight = accumulatedChance;
        entries.add(ent);
    }

// По шкале, селектим нужный предмет

    public int getRandom() {
        double r = rand.nextDouble() * accumulatedChance;
        int returnedObj = entries.get(0).object;
        for (RandomizeEntry entry : entries) {
            if (r >= entry.accumulatedWeight) {
                returnedObj = entry.object;
            }
        }
        return returnedObj;
    }
}


Спасибо за внимание!)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...