Я не впевнений, чи читаєте ви все ще, але я довго боровся з такою проблемою.
Я створив безліч різних типів афектних систем. Я зараз коротко перейду їх. Все це грунтується на моєму досвіді. Я не претендую на те, що знаю всі відповіді.
Статичні модифікатори
Цей тип системи в основному покладається на прості цілі числа для визначення будь-яких модифікацій. Наприклад, від +100 до Макс. HP, +10 для атаки тощо. Ця система також може впоратися з відсотками. Вам просто потрібно переконатися, що укладання не виходить з-під контролю.
Я ніколи не кешував створені значення для цього типу системи. Наприклад, якби я хотів показати максимальне здоров'я чогось, я б генерував значення на місці. Це не дало речей схильності до помилок і просто простіше зрозуміти всім, хто бере участь.
(Я працюю в Java, тому наступним є Java, але вона повинна працювати з деякими модифікаціями для інших мов) Цю систему можна легко зробити за допомогою перерахунків для типів модифікації, а потім цілих чисел. Кінцевий результат можна помістити в якусь колекцію, яка має ключові, упорядковані парами значення. Це буде швидкий пошук і розрахунки, тому продуктивність дуже хороша.
Загалом, це дуже добре працює з просто вирівняними статичними модифікаторами. Хоча код повинен існувати у відповідних місцях для модифікаторів, які будуть використовуватися: getAttack, getMaxHP, getMeleeDamage тощо, тощо.
Якщо цей метод не вдається (для мене), це дуже складна взаємодія між любителями. Немає справжнього простого способу взаємодії, за винятком того, як трохи його гетто. У нього є кілька простих можливостей взаємодії. Для цього потрібно внести зміни в спосіб зберігання статичних модифікаторів. Замість використання enum в якості ключа ви використовуєте String. Ця рядок буде ім'ям Enum + додатковою змінною. У 9 разів з 10 додаткова змінна не використовується, тому ви все одно зберігаєте ім'я enum як ключ.
Зробимо короткий приклад: Якщо ви хотіли б змінити збитки від неживих істот, у вас може бути впорядкована пара на зразок цього: (DAMAGE_Undead, 10) УРОК - це Enum, а Undead - додаткова змінна. Тож під час бою ви можете зробити щось на кшталт:
dam += attacker.getMod(Mod.DAMAGE + npc.getRaceFamily()); //in this case the race family would be undead
У будь-якому випадку, це працює досить добре і швидко. Але це не вдається при складних взаємодіях і наявності "спеціального" коду скрізь. Наприклад, розглянемо ситуацію "25% шансу телепортувати смерть". Це "досить" складний. Вищеописана система може впоратися з нею, але не легко, оскільки вам потрібно наступне:
- Визначте, чи є у гравця цей мод.
- Десь є якийсь код для виконання телепортації, якщо це вдасться. Розташування цього коду - дискусія сама по собі!
- Отримати потрібні дані на карті Mod. Що означає значення? Це кімната, де вони також телепортуються? Що робити, якщо у гравця є два модники телепорту ?? Чи не додаватимуться суми разом ?????? ЗБУД!
Отже, це приводить мене до наступного:
Кінцева складна система баффу
Я колись спробував написати 2D MMORPG власноруч. Це була жахлива помилка, але я багато чому навчився!
Я переписав афектну систему 3 рази. Перший використовував менш потужну варіацію вищезазначеного. Другий був про що я буду говорити.
Ця система мала ряд класів для кожної модифікації, тому такі речі, як: ChangeHP, ChangeMaxHP, ChangeHPByPercent, ChangeMaxByPercent. У мене було мільйон цих хлопців - навіть такі речі, як TeleportOnDeath.
На моїх заняттях було зроблено наступне:
- застосовувати вплив
- removeAffect
- checkForInteraction <--- важливо
Застосовуйте та видаляйте пояснення себе (хоча для таких речей, як відсоток, афект буде відслідковувати, наскільки він збільшив HP, щоб забезпечити, коли афект знищився, він би видалив лише додану суму. Це було баггі, лол та ін. мені знадобилося багато часу, щоб переконатися, що це правильно. Я все ще не мав хорошого почуття з цього приводу.).
Метод checkForInteraction був жахливо складним фрагментом коду. У кожному з класів афектів (тобто: ChangeHP), він повинен мати код, щоб визначити, чи слід це змінювати за допомогою вхідного афекту. Так, наприклад, якщо у вас було щось на кшталт…
- Buff 1: Наносить 10 вогневих збитків під час нападу
- Buff 2: Збільшує всю шкоду від пожежі на 25%.
- Buff 3: Збільшує всю шкоду від пожежі на 15.
Метод checkForInteraction обробляє всі ці впливи. Для цього потрібно перевірити кожен вплив на ВСІХ гравців, які знаходяться поруч !! Це тому, що тип афектів я мав справу з кількома гравцями протягом певного проміжку площі. Це означає, що за кодом НІКОЛИ НЕ БУДЬ будь-яких спеціальних тверджень, як вище - "якщо ми щойно померли, нам слід перевірити наявність телепорту на смерть". Ця система автоматично обробляла б її правильно в потрібний час.
Спроба написати цю систему мені зайняла як 2 місяці, і кілька разів зробила голову вибухом. ЯКЩО це було ДІЙСНО потужно і могло зробити божевільну кількість речей - особливо якщо взяти до уваги наступні два факти щодо здібностей у моїй грі: 1. Вони мали цільові діапазони (тобто: одиночний, самостійна, лише група, PB AE self , Ціль PE AE, націлена на AE тощо). 2. Здібності можуть впливати на них більше ніж 1.
Як я вже згадував вище, це була 2-я система 3-го афекту для цієї гри. Чому я відійшов від цього?
Ця система мала найгірші показники, які я коли-небудь бачив! Це було жахливо повільно, оскільки йому довелося стільки перевіряти кожну річ, що тривала. Я намагався його вдосконалити, але вважав це невдачею.
Тож ми підійшли до моєї третьої версії (та іншого типу буф-системи):
Комплексний клас афектів з обробниками
Таким чином, це в значній мірі поєднання перших двох: ми можемо мати статичні змінні в класі Affect, що містить багато функціональності та додаткових даних. Тоді просто зателефонуйте обробникам (для мене, як правило, деякі статичні корисні методи замість підкласів для конкретних дій. Але я впевнений, що ви можете піти з підкласами для дій, якщо ви хочете теж), коли ми хочемо щось зробити.
Клас Affect мав би всі соковиті продукти, такі як цільові типи, тривалість, кількість застосувань, шанс на виконання та інше тощо.
Нам все одно доведеться додавати спеціальні коди, щоб вирішити ситуації, наприклад, телепорт про смерть. Нам все одно доведеться перевірити це в бойовому коді вручну, і тоді, якби він існував, ми отримаємо список афектів. Цей перелік афектів містить усі застосовані в даний час впливи на гравця, який займався телепортацією про смерть. Тоді ми просто подивимось на кожну з них і перевіримо, чи вона виконана та чи вдала (Ми зупинилися б на першій успішній). Це було успішно, ми б просто зателефонували обробнику, щоб подбати про це.
Взаємодія може бути здійснена, якщо ви теж хочете. Було б просто написати код, щоб шукати конкретні бафи на програвачах / тощо. Оскільки він має хороші показники (див. Нижче), це слід досить ефективно робити. Просто знадобляться складніші обробники тощо.
Таким чином, вона має велику продуктивність першої системи і ще багато складності, як і друга (але не настільки багато). Принаймні, у Java ви можете зробити деякі хитрі речі, щоб досягти продуктивності майже першої у випадках, що найчастіше (тобто: мати карту перерахунку ( http://docs.oracle.com/javase/6/docs/api/java /util/EnumMap.html ) із ключами Enums та ArrayList афектів як значення. Це дозволяє вам побачити, чи швидко у вас впливає [оскільки у списку було б 0 або на карті не було б перерахунку] і не було постійно повторювати переліки афектів гравця без будь-якої причини. Я не проти повторювати афекти, якщо вони нам зараз потрібні. Я згодом оптимізую, якщо це стане проблемою).
В даний час я знову відкриваю (переписую гру на Java замість кодової бази FastROM, в якій вона була спочатку), мій MUD, який закінчився в 2005 році, і я нещодавно зіткнувся з тим, як я хочу реалізувати свою баф-систему? Я буду використовувати цю систему, тому що вона добре працювала в моїй попередній невдалій грі.
Ну, сподіваємось, хтось десь знайде кілька цих поглядів корисними.