BeaRLibItems - удобный менеджмент предметов в рогалике

Форум библиотеки BeaRLib

Модератор: Apromix

Аватара пользователя
warchief
Сообщения: 300
Зарегистрирован: 11 янв 2008, 09:55
Откуда: Озеро снов

Re: BeaRLibInv

Сообщение warchief » 12 окт 2011, 09:58

В таком случае зачем пользователю эта библиотека, когда обозвать свою переменную int damage и сделать пару функций конструктор/деструктор
Затем что кроме int damage там есть и другие возможности реализованные системой ключевых слов (снова посмотрите пример описания примера - там не для красоты строка key)

Взаимодействие предмета с миром все равно ложится на плечи пользователя, потому что невозможно угадать законы мира пользователя.
Влияние предмета на характеристики монстра
вместо:
monstr.att = item.att + monstr.str;
Будет:
monstr.att = itoa(item.GetParam("атака").c_str()) + monstr.str;
Не вижу сложности.

Но это же позволит например привязывать предметы с заклинаниями, и делать очень сложные системы предметов

Влияние между самими предметами будут определены контейнером (замена нескольких предметов одним, стековая система (для тех же стрел), перемещения предметов по контейнерам, и т.д.)

Аватара пользователя
warchief
Сообщения: 300
Зарегистрирован: 11 янв 2008, 09:55
Откуда: Озеро снов

Re: BeaRLibInv

Сообщение warchief » 12 окт 2011, 10:03

Так, предмет сделал (весь код объявление - viewtopic.php?p=15613#p15613)
Теперь надо думать над контейнерами. А после них над интерфейсом и можно считать что библиотека готова

Аватара пользователя
alexbard
Сообщения: 670
Зарегистрирован: 22 апр 2011, 17:15
Откуда: Украина
Контактная информация:

Re: BeaRLibInv

Сообщение alexbard » 12 окт 2011, 10:22

Сложное взаимодействие для внешней библиотеки. Для самого пользователя прикрепить заклинание (или эффект) к предмету выглядит как-то так:

item.onHitCast += new spell (spellFireball);

в случае же этой системы придется создавать конструкцию типа:

t.AddParam("spell", "spellFireball");

и где-то дальше обработка:

switch (t.getParam("spell"))
{
case "spellFireball":
spellFireball.Invoke();
break;
}
и так по case на каждый спелл, что исключит также динамическое создание заклинаний и т.д.

Аватара пользователя
Феникc
Сообщения: 679
Зарегистрирован: 27 ноя 2010, 15:01
Откуда: Челябинск

Re: BeaRLibInv

Сообщение Феникc » 12 окт 2011, 10:34

Всё вышесказанное - ИМХО, если не указано обратное.

Аватара пользователя
warchief
Сообщения: 300
Зарегистрирован: 11 янв 2008, 09:55
Откуда: Озеро снов

Re: BeaRLibInv

Сообщение warchief » 12 окт 2011, 11:10

alexbard писал(а): и так по case на каждый спелл, что исключит также динамическое создание заклинаний и т.д.
А если спеллы хранить по такой же системе ключ/значение? Тогда это будет так:

Код: Выделить всё

t.AddParam("spell", "spellFireball");
spell[t.GetParam("spell")].Invoke();
Всего две строчки без проверок. Расширяемость

Аватара пользователя
alexbard
Сообщения: 670
Зарегистрирован: 22 апр 2011, 17:15
Откуда: Украина
Контактная информация:

Re: BeaRLibInv

Сообщение alexbard » 12 окт 2011, 11:59

Допустим, но конкретный Invoke() под каждый spell[t.GetParam("spell")] еще определить надо, и тогда проверки будут именно в той части кода (и в ходе t.GetParam("spell"), кстати) Ладно.

Но с библиотекой, комбинирование предметов становится затрудненным (не невозможным), т.к. предмет из простого предмета должен уметь превратиться в контейнер для нескольких других, не теряя своих свойств. Это как минимум одна ссылка, а дальше начинается невозможность возвращения комплексных объектов, сложности со структурами и т.д.

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

Код: Выделить всё

void damageItem(int damageValue)
{
 int damage = damageValue-hardness;
 if (damage > 0) durability -= damage;
 if (durability < durabilityMax * 0.35 && !damaged) makeItemDamaged();
}
...в коде с внешней библиотекой, придется переписывать в виде дополнительной надстроки. Я не понимаю, для чего нужна подобная децентрализованная система ? Неужели существуют программисты, которые могут написать интересную систему вещей, но при этом е могут сделать проверку на стакинг ?

Аватара пользователя
kipar
Сообщения: 2120
Зарегистрирован: 10 мар 2010, 13:16
Откуда: Москва

Re: BeaRLibInv

Сообщение kipar » 12 окт 2011, 13:03

Да, я тоже думаю что предметы достаточно представить в виде (void *), т.е. указателя. А библиотека работы с инвентарем должна эти void* группировать, перемещать между сумками, выбрасывать и т.д.
Соответственно простой рогалик может вообще интерпретировать эти void* как числа (1 - меч, 2 - щит, 3 - снадобье), а в сложном можно например map использовать.

Единственное, что может стоит хранить из информации о предмете - количество. Правда тут неоднозначно, у кого-то количество является свойством предмета, у кого-то на каждую "штуку" предмета отдельный объект, так что надо или предусмотреть все варианты или выбрать какой-то один.

Есть конечно и другие параметры объекта, которые могут понадобиться в InvLib, например ограничение веса. Но их имхо лучше сделать колбэками для гибкости. Скажем, функция проверяющая можно ли взять предмет А в сумку В будет предоставляться пользовательской программой, а вызываться из библиотеки.

Аватара пользователя
warchief
Сообщения: 300
Зарегистрирован: 11 янв 2008, 09:55
Откуда: Озеро снов

Re: BeaRLibInv

Сообщение warchief » 12 окт 2011, 13:19

alexbard писал(а):еще определить надо
Не понял.
Значением ключа может быть класс, тогда ничего не надо определять

Код: Выделить всё

struct Spell
{
...
...
void Start();
};

std::map<std::string,Spell> SpellList;

SpellList[t.GetParam("spell")].Start();

Все еще остается две строки.
alexbard писал(а):т.к. предмет из простого предмета должен уметь превратиться в контейнер для нескольких других, не теряя своих свойств
У меня предмет не будет превращаться в контейнер. Точнее не так - контейнер может содержать любое число предметов... в Том числе и 1. Контейнер может содержать другие контейнеры. Инвентарь содержит не предметы а контейнеры, которые тоже могут содержать другие контейнеры.
alexbard писал(а):Я не понимаю, для чего нужна подобная децентрализованная система ? Неужели существуют программисты, которые могут написать интересную систему вещей, но при этом е могут сделать проверку на стакинг ?
Будет еще и интерфейс (третий уровень - первый - предмет, второй - контейнер) который будет надстройкой над всей этой системой, и в котором уже будут заготовки под базовые желания пользователя (крафтинг, или привязка событий к использованию предметов и т.д.) Я еще конечно не полностью сам представляю этот третий уровень. И поэтому предлагаю здесь высказывать свои идеи (а особенно лучше если они будут по контейнерам).
Если добавить много фич, то будут и пользователи. Но сама абстрактная система при этом не ограничивает их в их фантазиях
kipar писал(а):Да, я тоже думаю что предметы достаточно представить в виде (void *), т.е. указателя.
Ну если так, то я подумаю над возможностью выкинуть BR_Item и использовать только контейнеры.

Аватара пользователя
alexbard
Сообщения: 670
Зарегистрирован: 22 апр 2011, 17:15
Откуда: Украина
Контактная информация:

Re: BeaRLibInv

Сообщение alexbard » 12 окт 2011, 13:43

Ну вот был у тебя предмет меч в контейнере рюкзак. Ты вставил ему в рукоятку предмет рубин. Характеристики меча изменились, рубин из рюкзака пропал. Через некоторое время, ты захотел сломать рубин и вставить топаз. Должен быть механизм, который тем или иным образом будет отслеживать происходящие с предметом изменения. Без предмета, который может содержать другие предметы - нужно придумывать что-то иное.

По-контейнерам? Легко: должна быть возможность вывода списка предметов, желательно с опциональной сортировкой по разным критериям(причем, я думаю, что в случае с библиотекой пользователь должен иметь возможность создания собственного критерия). Должна быть возможность уничтожения предметов, преобразования из одного в другие, возможность переложить предмет из одного контейнера в другой.

Но, по-сути, все это не контейнер, а уже интерфейс пользователя для работы с библиотекой.

Аватара пользователя
Apromix
Мастер
Сообщения: 1236
Зарегистрирован: 04 июл 2011, 10:44
Откуда: Украина, Черновцы
Контактная информация:

Re: BeaRLibInv

Сообщение Apromix » 17 окт 2011, 13:28

Для начала нужно реализовать базовый вариант библиотеки с несколькими возможностями, но чтобы все работало и было удобно для добавления в проекты, а уже потом будем наращивать возможности и дополнительный функционал :D Как вариант могу взять код из HoD'a и перенести в .dll :D

Аватара пользователя
Apromix
Мастер
Сообщения: 1236
Зарегистрирован: 04 июл 2011, 10:44
Откуда: Украина, Черновцы
Контактная информация:

Re: BeaRLibInv - инвентарь и "кукла" персонажа

Сообщение Apromix » 08 фев 2017, 12:56

Итак, перечитал все посты, предлагаю сделать в таком виде:

I. Три группы методов в библиотеке:
  • Пол - список предметов на полу подземелья.
  • Персонаж - список надетых на персонажа предметов.
  • Инвентарь - список предметов в инвентаре персонажа.
В каждой группе несколько необходимых методов, как clear, size, count, indexof и т.д. Также методы глобального конфигурирования библиотеки, записи в лог и т.д.

II. Я как-то все всегда упрощаю, мне видятся эти списки массивами целых чисел, ID предметов из базы всех предметов игры. Библиотека предоставит удобные методы для работы с такими списками. Иначе если сделать объектами со многими полями, то всем не угодишь, у каждого свое понимание предмета и его полей.

Дальше, все другие доп. опции предмета предлагаю передавать в либу в виде строки OPTIONS. Все параметры в ней разделены разделителем. Это позволит сделать для предмета разрушаемость, зачарование, апгрейд и тд.

В итоге мы имеем запись предмета для списка, где только только ID (целое число) и OPTIONS (строка). Думаю больше ничего и не нужно.

Аватара пользователя
kipar
Сообщения: 2120
Зарегистрирован: 10 мар 2010, 13:16
Откуда: Москва

Re: BeaRLibInv - инвентарь и "кукла" персонажа

Сообщение kipar » 09 фев 2017, 11:38

Строка сразу ограничит применимость.
Либо надо будет хранить у себя свойства в своем виде (разных структур и классов) и переводить в строку для обращения к библиотеке, либо у себя тоже хранить в строке и для любых операций с предметом это строку разбирать, искать там нужный параметр, а потом собирать заново с новым параметром. Оба варианта по-моему провал.
Так что я согласен со своим предыдущим постом - Для любых дополнительных данных должен быть указатель, содержимое которого библиотеку не интересует. Да и для ID, по-моему, лучше сделать указатель, кому надо всегда смогут интерпретировать его как число.
Вопрос только как передавать данные которую библиотеку все-таки интересуют (и делать ли вообще такие данные). Если не делать - получается просто библиотека про работу с тремя списками указателей? Звучит сомнительно, списки и так в любом языке есть.

Аватара пользователя
Apromix
Мастер
Сообщения: 1236
Зарегистрирован: 04 июл 2011, 10:44
Откуда: Украина, Черновцы
Контактная информация:

Re: BeaRLibInv - инвентарь и "кукла" персонажа

Сообщение Apromix » 09 фев 2017, 13:23

Инвентарь такой инвентарь :) Мне тож не особо нравится строка, но лучше пока не придумал. Для загрузки базы предметов, для вывода на экраны, для учета, как надетые шмотки влияют на параметры персонажа, для разборки и сборки строки написать методы автору придется, но остальное он получит сразу из коробки. Ну точно половину не придется писать.

Можно конечно предусмотреть все и передавать предмет как запись со всеми параметрами предмета, что не используется -1 или "". Но как предусмотреть все-все-все?

Аватара пользователя
kipar
Сообщения: 2120
Зарегистрирован: 10 мар 2010, 13:16
Откуда: Москва

Re: BeaRLibInv - инвентарь и "кукла" персонажа

Сообщение kipar » 10 фев 2017, 08:18

Apromix писал(а):
09 фев 2017, 13:23
передавать предмет как запись со всеми параметрами предмета, что не используется -1 или ""
библиотеке не надо никаких записей со всеми параметрами. Ей нужны только те параметры которые она использует.

В общем, простейший вариант. Библиотека умеет вести список предметов, добавлять туда элементы, удалять, возвращать длину и сами элементы. Что ей в этом случае нужно знать о предмете? Ровным счетом ничего. Для нее это просто абстрактный объект. Например указатель. Что там пользователь будет хранить - id или свойства, ей без разницы.

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

Допустим, мы добавим в библиотеку контроль веса и объема. В этом случае библиотеке кроме абстрактного указателя потребуется знать вес и объем предмета. Правда по-моему смысла в добавлении их будет мало, т.к. вся польза от библиотеки заменяется двумя строчками "if(объем <= максимального)then добавить else не добавить".

Интересным было бы добавить автоматическое складывание однотипных предметов в стопки, т.к. все-таки уже реализация получается неочевидной (с другой стороны и интерфейс библиотеки усложняется). Тогда библиотеке потребуется кроме указателя знать количество объектов в стопке. При этом тот кто никакого складывания не хочет просто не будет передавать туда количество.

В целом можно даже и строку использовать (хотя имхо это лишние тормоза), главное что не надо хранить в ней всё чего хочет пользователь. То что ему надо он сохранит в указателе удобным ему способом, и параметры и зачарования и что хочет. В строке\другой структуре надо хранить те свойства которые использует библиотека. А что это за свойства - зависит от функционала библиотеки.

altmax
Сообщения: 173
Зарегистрирован: 15 сен 2012, 11:59

Re: BeaRLibInv - инвентарь и "кукла" персонажа

Сообщение altmax » 12 фев 2017, 14:44

Apromix писал(а):
08 фев 2017, 12:56
Итак, перечитал все посты, предлагаю сделать в таком виде:

I. Три группы методов в библиотеке:
  • Пол - список предметов на полу подземелья.
  • Персонаж - список надетых на персонажа предметов.
  • Инвентарь - список предметов в инвентаре персонажа.
То что лежит на полу - оно как бы относится больше к карте уровня, т.е. на каждом тайле есть, список, где храним лежащие там предметы. Если ничего нет, то он просто пустой, но он есть в структуре, описывающей тайл. Храним только id вещи.

Думаю, что где-то в памяти должен лежать массив структур, где каждый элемент описывает один из возможных в игре предметов. Если предметы можно улучшать, то в структуре обязательно должна быть ссылка на наследника. Массив предметов должен читаться из файла (чтобы создавать список и корректировать без перекомпиляции приложения) Да еще можно создать приложение для генерации предметов.

Идеально конечно бы подошла sql база данных, но в данном случае это больше похоже на забивание гвоздей микроскопом. Хотя если предметов в игре прямо ну очень много, плюс у них бывают разные характеристики, возможны улучшения, крафт, разборка на составные части - возможно посмотреть и в сторону базы данных.. С базой данных вообще было бы удобно работать - выбрал из ней все предметы, относящиеся к броне уровней например 5-8 и несколько случайных предметов из выборки раскидал по уровню. А из массива придется методом перебора выбирать различные группы элементов.

Ну а у персонажа инвентарь, экипировка - там лежат только id вещи.

При использовании базы данных вообще всё можно было бы хранить в ней. И никаких проблем с сериализацией данных игры при её сохранении. И так же при загрузке - просто подключить нужную базу.

Какие есть самые простые и легкие бесплатные базы данных, которые можно запихнуть в dll? А то что-то меня эта идея прямо очень заинтересовала.

Ответить

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 11 гостей