TidalPoo Posted June 17, 2021 Share Posted June 17, 2021 … или почему комьюнити фришек всегда жалуется и будет жаловаться на дроп. Итак, если вы заглянули в эту статью, то я думаю вы представляете себе, что такое фришка 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; } } Спасибо за внимание!) Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.