ScorpioT1000
Работаем
offline
Опыт: отключен
|
prog, это делается в пять строк давай придумаем уникальный кейворд и я напишу ту, которая парсит перед cJass |
21.02.2012, 18:59 | #21
+0/−1
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
prog
offline
Опыт:
32,865Активность: |
распарсить код карты регуляркой не проблема - просто на мой взгляд это избыточно.
prog:
|
21.02.2012, 19:05 | #22
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
ScorpioT1000
Работаем
offline
Опыт: отключен
|
мда, регуляркой по файлу - это сильно =) ну успехов вобщем ... |
21.02.2012, 20:19 | #23
+0/−1
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
prog
offline
Опыт:
32,865Активность: |
ScorpioT1000, да, если скрипт большой - будет долго) вот домой с работы вернусь - что-нибудь запилю. |
21.02.2012, 20:43 | #24
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Alex_Hell
Mapmaker 'N' Programmer
offline
Опыт:
6,885Активность: |
На счет списка полей - я считаю что можно подгрузить все возможные поля. Хотя тут нужно смотреть производительность. Предложили вариант - смотреть какие поля используются, и только их загонять в структуру - тоже способ, определить это не сложно - найти все обращения к конкретным свойствам структуры типа UnitInfo.Name, UnitInfo.Description, и только для используемых сгенерить БД.
Количество сохраненных юнитов, предметов - опять таки можно все сохранить. Нужно кнечно тестить производительность. Но я уверен что хоть 100 хоть 1000 юнитов будут почти одинаково влиять на производительность - это же шех таблица, она для этого и предназначена, в крайнем случае можно разбить на несколько хеш-таблиц, в каждой допустим храняться данные по 100 юнитам, тогда на начальном этапе нужно будет выбрать одну из таблиц, а уже потом внутри нее нужного юнита. Распределение по таблицам пусть делает прога, она например заводит
Hashtable UnitTable[count] и внутри метода UnitInfo UnitInfo.create(int id)
{ integer tableIndex UnitInfo info = info.allocate() if (id <= 'B000')
{ tableIndex = 0 } elseif if (id <= 'C000') { tableIndex = 1 } или арифметически: tableIndex = (id - 'A000') / 100
UnitTableKey_Description - константа info.Name = LoadString(UnitTable[tableIndex], id, UnitTableKey_Name) info.Description = LoadString(UnitTable[tableIndex], id, UnitTableKey_Description) return info
} либо можно массив структур UnitInfo сгенерить заранее, а в хеш-таблице хранить только позицию внутри этого массива - не нужны каждый раз аллокации
ScorpioT1000:
это у какого объекта 1000 полей?
У юнита вроде всех больше, так там вроде сотня от силы Кстати регулярка там будет довольно простая. Я сам писал прогу, модифицирующую j-скрипт, которая назодила там блоки функций, переменные, обращения к определенным переменным. Тут нужно всего-то найти внутри блока функции создание переменной типа UnitInfo.create(), запомнить в какую локалку это помещается, а дальше, в рамках этой функции найти все обращения к этой переменной, а именно info.Name, info.Description, и т.д. список которых ограничен, и для всех которые найдены - добавить в результирующий set<string>. Если запись идет в глобалку - искать дополнительно по всему файлу придется. Тогда в set<string> будет набор имен полей, которые надо парсить из файла карты. Ну уж парсинг сделать - dictionary<string, X> где ключ - имя поля для парсинга (Name, Description), X - структура информации достаточной для парсинга, это может быть offset внутри файла и т.д. я не разбирался как там внутри war3map.w3u храняться данные. Отредактировано Alex_Hell, 21.02.2012 в 22:59. |
21.02.2012, 22:43 | #25
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
prog
offline
Опыт:
32,865Активность: |
Alex_Hell, господи, а время нужное чтобы это все в память во время старта карты подгрузить ты учитываешь? А способности многоуровневые ты учитываешь? |
21.02.2012, 22:56 | #26
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Alex_Hell
Mapmaker 'N' Programmer
offline
Опыт:
6,885Активность: |
prog, заполнить хеш-таблицу? Очень быстро)) Ты сделай тест и провериш, нам скажеш)) Я же сказал - нужно мерять производительность, если медленно - грузить только используемые поля (см выше) и используемые объеты (юниты, предметы) - помечать отдельно saved как ты указал или как-то так
Alex_Hell добавил: Ребят, а вы не вкурсе, в SC2 есть что-то подобное? Вроде возможности во время игры обращаться к любым полям юнитов и еще круче возможность их изменять прямо во время игры? Было бы интересно не плодить кучу предметов с разным описанием (например бонусов в зависимости от сокетов), а сделать 1 предмет, а потом во время игры сделать что-то вроде myItem.Description = myGlobalDescription + "бонус: 100 ХП". Сейчас это предполагается обходить постпроцессором, генерящим предметы на основе базового, а я пишу о возможности динамически во время игры менять все характеристики и описания |
21.02.2012, 23:17 | #27
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
prog
offline
Опыт:
32,865Активность: |
Alex_Hell, в ск2 точно есть возможность обращаться к этим данным - оттуда и почерпнул вдохновение, насчет изменения не уверен, кажется тоже можно, но не все.
В варе ты динамически во время игры ты ничего не поменяешь. Вернее характеристики можно изменить если изначально сделать систему кастомных характеристик предметов, а вот описания предметов никак не поменять, не вмешиваясь в память игры извне.
П.С. Свою утилиту в процесс сохранения карты JNGP вклинил, файлы с данными утилите скормил, теперь надо научить ее разбирать этот формат. |
21.02.2012, 23:44 | #28
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
ScorpioT1000
Работаем
offline
Опыт: отключен
|
Alex_Hell, регексп медленный, я готов написать приложение / либу на C++, которая проходит по файлу - по каждому символу - 1 раз, одна проверка (кроме совпадений), это дело 5 минут
нельзя нормально... ну точнее есть одна штука, контейнер - GetAbilityEffectById а в абилку можно запихать сколько угодно любых строк, через запятую O_O я это юзал, но опятьже нельзя менять ScorpioT1000 добавил:
=) |
21.02.2012, 23:48 | #29
+0/−1
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
prog
offline
Опыт:
32,865Активность: |
ScorpioT1000, я то на Java пишу и либа на C++ мне не очень поможет) но это я разленился просто - никто мне не помешает сделать все что надо и без регулярок. |
22.02.2012, 00:03 | #30
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
prog
offline
Опыт:
32,865Активность: |
Научил утилиту читать из файла данные по объектам. Пока только отклонения от стандартных значений. Еще немного и первая дубовая версия будет готова. |
23.02.2012, 00:39 | #31
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
J64_
offline
Опыт:
4,724Активность: |
Alex_Hell:
без аллокации структур:
алсо, как я знаю, максимальное количество хеш-таблиц 255 |
23.02.2012, 15:51 | #32
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Alex_Hell
Mapmaker 'N' Programmer
offline
Опыт:
6,885Активность: |
Judycaster64, мне не очень ясно что этот код делает, даже комментов нет. И как это конструируется структура RawcodeData_Unit у которой aa, bb, cc из результата возврата GetObjectId('H0FF') который int?
К тому же мой вариант вполне подходящий.
На примере как может быть... Юниты в карте такие:
A000 ... A010 ... A020 Разделение по хеш-таблицам:
первые 256 юнитов в первой таблице (от A000 до A010) вторые 256 юнитов во второй таблице (от A011 до A020) и т.д. Хеш-таблицы уже заполнены значениями:
В первой таблице: Key1 * Key2 * Value 'A000' * Hash("Name") * "Unit1" 'A000' * Hash("Description") * "UnitDesc1" 'A000' * Hash("AddInfo") * "AddInfo1" 'A001' * Hash("Name") * "Unit2" 'A001' * Hash("Description") * "UnitDesc2" 'A001' * Hash("AddInfo") * "AddInfo2" ... и во 2й:
Key1 * Key2 * Value 'A011' * Hash("Name") * "Unit257" 'A011' * Hash("Description") * "UnitDesc257" 'A011' * Hash("AddInfo") * "AddInfo257" 'A012' * Hash("Name") * "Unit258" 'A012' * Hash("Description") * "UnitDesc258" 'A012' * Hash("AddInfo") * "AddInfo258" ... Либо если сделать через массив структур (аллокации заранее):
Массив структур:
UnitInfo {Name = "Unit1", Description = "UnitDesc1", AddInfo = "AddInfo1"} UnitInfo {Name = "Unit2", Description = "UnitDesc2", AddInfo = "AddInfo2"} ... UnitInfo {Name = "Unit257", Description = "UnitDesc257", AddInfo = "AddInfo257"} UnitInfo {Name = "Unit258", Description = "UnitDesc258", AddInfo = "AddInfo258"} ... А в хеш-таблицах тогда:
в 1й: Key1 * Key2 * Value (Key2 = не играет роли, Value = индекс к массиву структур) 'A000' * 0 * 0 'A001' * 0 * 1 во 2й:
Key1 * Key2 * Value 'A011' * 0 * 257 'A012' * 0 * 258 Вроде бы Value = Key1 - 'A000'?
Но в случае когда не по всем юнитам нужно сохранять данные, а только отмеченных признаком, их ID например: A000 A005 A009 A011 A021 A031 Массив структур будет последовательно заполнен данными именно этих юнитов:
UnitInfo {Name = "Unit0", Description = "UnitDesc0", AddInfo = "AddInfo0"} UnitInfo {Name = "Unit5", Description = "UnitDesc5", AddInfo = "AddInfo5"} ... Если предположить что в таблице 3 юнита (для примера)...
в 1й хеш-таблице будет:
Key1 * Key2 * Value 'A000' * 0 * 0 'A005' * 0 * 1 'A009' * 0 * 2 во 2й хеш-таблице будет:
'A011' * 0 * 3 'A021' * 0 * 4 'A031' * 0 * 5 Получение данных юнита по его ID:
Писал по памяти, возможно синтаксис или имена функций не корректны)) Отредактировано Alex_Hell, 23.02.2012 в 22:11. |
23.02.2012, 21:53 | #33
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
ScorpioT1000
Работаем
offline
Опыт: отключен
|
Alex_Hell, не надо структуры, надо функции. это было бы круто если бы были плюсы или ява, но тут лучше функции, плюс в том что сижасс может их выпилить потом =) если не юзаются, а вжасс - инлайнить
хештаблицы не нужны, лучше сделать на примере XAT - 8 массивов строк по 8190 элементов, которые абстрагированы функциями доступа как 1 большой массив, а обращаться к ним через индексы
потом заполняем его подряд данными, создаем набор констант - типов полей, например
#define UNIT_NAME = 12 и функции типа OE_LOAD('A001', UNIT_NAME) - функция обращается к определенной ячейке юнита со смещением == UNIT_NAME |
23.02.2012, 22:21 | #34
+0/−1
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Doc
offline
Опыт:
63,163Активность: |
это просто омфг, зачем? |
23.02.2012, 23:07 | #35
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
prog
offline
Опыт:
32,865Активность: |
ScorpioT1000, java читается как джава. Прочтение ява не признается как допустимое ни Sun ни Oracle.
По поводу хранения данных расскажи поподробнее, а лучше напиши код примера - я какраз дошел до генерации кода утилитой - пока пилю просто дефайны, но скоро и до базы доберусь. Учти только что данные не только строковые бывают, но и числовые и даже многострочные(хранятся то они как одна строка, но логика подсказывает что логично их распарсить для удобства обращения), не говоря уже о равкодах и списках равкодов. |
23.02.2012, 23:14 | #36
+1/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
ScorpioT1000
Работаем
offline
Опыт: отключен
|
давай тогда напишу базу, скину щас
кодВот код, смотри всё что закомменчено "GENERATE":
» открыть код
задача программытоесть твоя утила должна в этом коде добавить следующее:
задать OEU_COUNT как число этих полей
баффы и декорации пока не сделал, реализуй сначала это
строки предлагаю положить на пользователя, ему ведь нетрудно будет конвертить из строки в число, а вот нам рассчитвать все комбинации будет нелегко
есть еще проблема - здесь только для кастомных полей. для стандартных надо еще сделать дополнение, но сделай хотябы так, а то я потратил полтора часа уже на это =)
ScorpioT1000 добавил: кароче я уже придумал как сделать для любого равкода, тока там надо изначально знать равкод с самым маленьким индексом, вобщем, позже добавлю одну функцию, в которую надо будет передать все стандартные равкоды перед заполнением бд, сделай это покачто Отредактировано ScorpioT1000, 24.02.2012 в 01:29. |
24.02.2012, 01:43 | #37
+0/−1
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
prog
offline
Опыт:
32,865Активность: |
ScorpioT1000, пользователю то не трудно, конечно, превратить строку в число, но как быть со случаем когда в строке записаны, например, равкоды через запятую? Парсить это на jass повеситься можно, если с проверкой валидности исходных данных. С Массивами строк в поле еще хуже.
ИМХО надо немного усложнить структуру хранения данных, но обеспечить возможность доступа к таким составным полям без геморроя.
Также у тебя не учтены многоуровневые способности, на сколько я вижу.
Т.Е. твой способ годится только для юнитов, предметов, разрушаемых объектов и бафов. Для способностей и декораций надо делать подругому.
Со стандартными равкодами я вообще не уверен стоит ли возиться на данном этапе. |
24.02.2012, 02:03 | #38
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
ScorpioT1000
Работаем
offline
Опыт: отключен
|
prog, поля сделай покачто через запятую, на жассе парсить это затратно, но лучше парсить на жассе, т.к. это будет ввод лишнего измерения =) я могу предоставить просто отдельные функции типа "считать это массивом" ну как OELoadUnitDataList(rawcode, data_type) вернет допустим какуюто сижасс структуру с функциями доступа, вобщем это щас не так важно, уверен еще будут проблемы поважнее, сделай пока это Что касается уровней - ок, введу для абилок уровни, не проблема =) Отредактировано ScorpioT1000, 24.02.2012 в 02:33. |
24.02.2012, 02:27 | #39
+0/−1
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
prog
offline
Опыт:
32,865Активность: |
Кстати, можно же заставить WE подгрузить slk таблицы не из архива игры, правильно? значит можно в РО добавить свои поля и использовать их так как нам надо. А карте, предназначенной для запуска, этих полей и близко не будет чтобы вар на них случайно не ругнулся - все равно же делать два набора данных - для редактирования и для запуска.
Есть кандидат на использование в качестве препроцессора для описаний
FreeMarker
ссыль на документацию Думаю, эта библиотека более чем подойдет.
Примерно так может выглядеть описание способности:
((код
Это способность ${A000.name} и она выносит мозг цели на n секунд.|n
<#list A000.levels as level> Уровень ${level}: выносит на ${level.dur} сек.|n </#list> А если цель под воздействием заклинания "${A002.name}" то эффект длится в 2 раза дольше. )) В игре это может выглядеть так:
((код
Это способность Взрыв Мозга и она выносит мозг цели на n секунд.
Уровень 1: выносит на 1 сек. Уровень 2: выносит на 1 сек. Уровень 3: выносит на 2 сек. Уровень 4: выносит на 3 сек. А если цель под воздействием заклинания "Отупение" то эффект длится в 2 раза дольше. )) Единственная проблема - ограничение на количество символов в описании. В игре увеличить не удастся, скорее всего, а вот в РО можно попробовать - чтобы влезали шаблоны для более сложных описаний.
В базу, конечно, пойдет уже готовое описание - чтобы не нагружать jass ненужной работой. Отредактировано prog, 24.02.2012 в 06:53. |
24.02.2012, 03:37 | #40
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|