Ответы:
Используйте такую структуру, чтобы представить дерево в базе данных:
#Talent
id parent description
1 0 Tackle
2 1 Kick
3 1 Punch
4 3 Fire Punch
И еще одна таблица для представления приобретенных талантов на пользователя
#UserTalent
id user talent
1 4 1
2 4 3
3 4 4
Вы можете программно проверять зависимости талантов, запрашивая полную таблицу талантов и создавая связанное дерево. Вы также можете сделать это с SQL, но это потребует либо рекурсивных вложенных выборок, либо большого количества запросов. Лучше сделай это в своем коде.
Если существует несколько зависимостей, как, например, Fire Punch
зависит от Punch
AND, Immolation
используйте две таблицы для представления графа зависимостей:
#Talent
id description
1 Tackle
2 Kick
3 Punch
4 Fire Punch
5 Immolation
#Depedency
id parent child
1 0 1
2 0 5
3 1 2
4 1 3
5 3 4
6 5 4
Я бы порекомендовал использовать дерево, где каждый узел представляет определенный талант / навык. В зависимости от того, заработал ли игрок талант, его детские таланты могут быть заработаны. Например, следующая структура данных
class Talent {
std::vector<Talent*> children;
bool earned;
};
Чтобы определить, какие таланты есть у игрока, вы берете основной талант и идете вниз по графику, пока не достигнете узлов талантов, где заработанное значение является ложным. Это также покажет, какие таланты доступны для получения: первый талант в каждой ветви от корневого таланта, где заработано, является ложным.
ptr_vector
может быть даже лучше.
В моей игре я делаю это так:
База данных:
reference_talent : содержит уникальный идентификатор, имя, эффект и т. д.
talent : id, playerid <- содержит все таланты, которые «усвоили» игроки.
Внутриигровая: (на сервере)
Я загружаю все reference_talents в «статический» (только для чтения) std :: map, чтобы я мог легко получить к ним доступ по их идентификатору.
Когда клиент проверяет игрока, я извлекаю все таланты из базы данных и сохраняю их в std :: vector, так что когда мне нужно вычислить характеристики и т. Д., Я получаю их в оперативной памяти. Я также отправляю таланты клиенту.
Вот и все (кроме сохранения новых талантов, конечно, это просто «ВСТАВКА» в таблице «талант» + сообщение для клиента).
Вы описываете это как отношение между разблокировщиками и разблокированными, как в этом уроке . Я предлагаю узнать больше о реляционной алгебре и базах данных. Это хороший способ для моделирования данных. Если вы научитесь запрашивать информацию из базы данных, вы можете легко смоделировать данные.
Я не знаю, сколько Вы знаете о модельных отношениях. Этот урок должен помочь вам в этом.
Я предполагаю, что WoW работает как на самом деле (эм), что это
Это отношение N: N, которое подразумевает, что «среднему человеку» нужно новое отношение между двумя талантами:
(talent who unlocks id, talent who is unlocked)
Таким образом, вы можете иметь талант A, разблокирующий B, C и D ((A, B), (A, C), (A, D)) и талант Y, разблокированный с помощью X, Z и W ((X, Y), ( Z, Y), (W, Y)). В императивном / процедурном / объектно-ориентированном языке вы бы сделали это в виде списка / массива пар, например:
var unlocks_unlocked = [[A, B],[A,C],[A,D],[X,Y],[Z,Y],[W,Y]];
Так что для «реального» примера Вы можете иметь:
... ["running fast", "jumping superhigh"], ["antigravity's child", "jumping superhigh"]
и это означает, что «сверхскоростной прыжок» получается после того, как у вас есть «быстро бегать» и «антигравитационные дитя».
Я не играл в Diablo в последнее время, но, возможно, это было только:
Это отношение 1: N:
You put "is unlocked by this talent's id" variable into talent's structure
нравится:
var Talent[8] = { "name": "superpower", "unlocked by": "being Clark Kent"};
UserTalent
таблица не нуждается в колонке автоключей.user
иtalent
могут быть только два столбца и составной ключ: они никогда не будут дубликатами, и вы никогда не будете запрашивать вid
любом случае.