Search the Community
Showing results for tags 'дроп'.
-
… или почему комьюнити фришек всегда жалуется и будет жаловаться на дроп. Итак, если вы заглянули в эту статью, то я думаю вы представляете себе, что такое фришка Aion, эмулятор сервера и так далее. Так вот, однажды когда мне попался исходный код фришек, я сначала не поверил своим глазам, но перепроверив все открытые исходники, убедился, что так оно и есть, и это кошмар. Как рассчитывается дроп в оригинальном Aion? У моба/НПЦ, которого игрок пытается убить, есть много гипотетических ящиков с дропом. 1 ящик, это основной дроп для типа моба, там лежат предметы, которые так или иначе выпадут в дроплист с определённым шансом. 2-N – ящиков с различными наборами предметов, с которого может выпасть один, и только один предмет. У каждого предмета есть свой шанс на выпадение. Однако формула расчета тут везде разная. Для основного дропа, каждый предмет рассчитывается отдельно. Если выражаться условно то в этот ящик закидываются столько удочек, сколько предметов в ящике. Если 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) Надеюсь мне удалось объяснить вам как это действует. Попробую показать на картинке, где шанс выбить шмотку будет виден нагляднее. А почему, спросите вы? Потому-что человек, который писал первую версию фришного сервера, был далекий от игровой механики, и до ума не довел. А те кто открывают сервера по сей день, покупают “корявые” сборки у “криворуких” разработчиков. Вот так вот. Нынешние разработчики не могут сделать систему взвешенного выбора) - 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; } } Спасибо за внимание!)