XEPOMAHT
Posts: 2356
|
(21.01.2021 10:16)igrik Wrote: так чем тебя этот генератор не устроил?
Жесткая привязка к номерам монстров. Для поддержки Тифона потребуется:
1. получить адрес структуры монстров из эровского RedirectMemoryBlock по идентификатору 7D0C90h (как делается - знает Берсеркер).
2. Если полученный адрес не равен 7D0C90h, значит имеем дело с Тифоном (или с Аметистом, х.з. как проверить конкретную загруженную dll на ЭРЕ), если нет - идут проверки Игрика, п.3 и далее уже пропускаются.
3. Прибавить к адресу структуры её размер (тифоновский: MonNum * sizeof._Creature_). Далее прибавить 56000. Попадаем на тифоновский Ban_Table.
4. Проверяем 1000 байтов на предмет разрешённости 1000 тифоновских монстров:
Code:
do { // ищем доступного монстра из разрешённых
result = Randint(0, 999);
} while ( !monArray[result] );
ну и так далее по коду Игрика.
|
|
21.01.2021 14:52 |
|
Berserker
Posts: 16657
|
|
21.01.2021 14:57 |
|
Raistlin
Posts: 1349
|
А может закинуть вот это все
Code:
// заполняем массив нулями (запрещяем всех монстров)
for (int i = 0; i < 1024; i++)
monArray[i] = 0;
// собираем массив монстров нужного уровня (разрешаем только этих монстров)
for (int i = 0; i <= count; i++) {
int lvl = o_CreatureInfo[i].level;
if (lvl >= mon_lvl_Lo && lvl <= mon_lvl_Hi)
monArray[i] = 1; // монстр нужного уровня
}
// исключаем несуществующих монстров
monArray[122] = 0;
monArray[124] = 0;
monArray[126] = 0;
monArray[128] = 0;
// исключаем Драколича
monArray[196] = 0;
// исключаем Супер Драконов (так делает SOD)
for (int i = 132; i <= 135; i++)
monArray[i] = 0;
// исключаем Боевые Машины
for (int i = 145; i <= 149; i++)
monArray[i] = 0;
// исключаем Богов
for (int i = 160; i <= 163; i++)
monArray[i] = 0;
// исключаем Командиров
for (int i = 174; i <= 191; i++)
monArray[i] = 0;
в OnGameEnter, а массив monArray сделать глобальным?
Создал новый глобальный мод: WoG Ultra Edition
|
|
21.01.2021 15:06 |
|
XEPOMAHT
Posts: 2356
|
(21.01.2021 14:57)Berserker Wrote: Для этого отсутствующие монстры не попадают в глобальный массив номеров существ вообще + есть отдельные индексированные глобальные массивы по уровням.
Да, только если памяти не жалко на списки отсортированных монстров. По оптимизации скорости ЦП верхний лимит для выборки случайного монстра можно заранее понизить (например для ERA+ он не 1000, а 221, если скляроз не изменяет, если пройтись по той же таблице запрета - всё что выше 221 байта будет в нулях). Лично я привык экономить память (наследство от консольного моддинга, где её всегда мало).
(21.01.2021 15:06)Raistlin Wrote: А может закинуть вот это все в OnGameEnter, а массив monArray сделать глобальным?
В Тифоне оно и так глобальное. Смысл в дубликате имеющегося массива?
(This post was last modified: 21.01.2021 15:17 by XEPOMAHT.)
|
|
21.01.2021 15:11 |
|
igrik
Posts: 2819
|
(21.01.2021 14:57)Berserker Wrote: Генератор, конечно, не оптимальный по скорости с вечным циклом и дырками. В Mixed Neutrals генерация монстра по уровню — операция O(1) (линейная).
Для этого отсутствующие монстры не попадают в глобальный массив номеров существ вообще + есть отдельные индексированные глобальные массивы по уровням. Не при каждом же вызове делать фильтрацию.
Этот код практически идентичен коду генератора СОДа, только массив состоит не из битов как СОДе, а из байтов.
С нынешними компами я не вижу проблемы быстродействия массива на 1024+196 итераций. К тому же его сложность так же линейная O(n).
Да, этот код можно хорошенько оптимизировать. Но это был лишь показательный пример.
(21.01.2021 15:06)Raistlin Wrote: А может закинуть вот это все в OnGameEnter, а массив monArray сделать глобальным?
Ты правильно код прочитал?)) Глобальным делать код не нужно. Таким образом потеряется смысл данного кода.
(21.01.2021 13:46)Raistlin Wrote: Кстати, это ведь код из game bug fixes extended.dll? Я чувствую, мне определенно стоит ознакомиться с исходниками.
Нет. Этот код вообще отдельно-написанный, и не существует ни в одном из моих плагинов.
(21.01.2021 13:46)Raistlin Wrote: P.S. Я работаю в девятнадцатой студии, и мне потребовалось сделать приведение типов при вызове функции b_MsgBox. Это, ясное дело, не проблема, но на всякий случай я Вас уведомляю.
Ты используешь заголовочники homm3.h?
Их для 19 студии вообще нужно полностью адаптировать. Правильнее тогда уже использовать заголовочники от Кавалериста (они насыщеннее и работают на новых студиях)
game bug fixes extended.dll || My Plugins || My GitHub
|
|
21.01.2021 15:40 |
|
XEPOMAHT
Posts: 2356
|
(21.01.2021 15:24)Raistlin Wrote: igrik пишет универсальный код, который должен работать как с Тифоном, так и без.
Ну так без Тифона можно просто добавить готовый массив на 196 монстров. И тогда вообще проверять/вычислять в OnGameEnter ничего не нужно. А в генераторе простая проверка: если есть Тифон, то используется таблица тифона, если нет - используется таблица на 196 монстров. То, что SoD эти данные каждый раз вычисляет - проблема содовского кода генератора монстров (который давно пора отправить на пенсию, что, например, давно сделано в MoP и никак не могут сделать на ERA).
Минусы:
1. на картах старых форматов будут генерироваться новые монстры. Думаю, что это не минус, а даже плюс.
2. не будет действовать запрет фракции Сопряжения (значение из базовой структуры) для определённых кампаний в игре. Но... ВоГ изначально создан как дополнение, вводящее Сопряжение в SoD. Поэтому думаю, что в рамках ВоГа это будет выглядеть нормально, что в каких-нибудь стандартных RoE/SoD-кампаниях сгенерируются, например, Фениксы или Аспиды.
(This post was last modified: 21.01.2021 16:28 by XEPOMAHT.)
|
|
21.01.2021 15:42 |
|
Berserker
Posts: 16657
|
|
21.01.2021 16:37 |
|
Raistlin
Posts: 1349
|
(21.01.2021 15:40)igrik Wrote: Ты правильно код прочитал?)) Глобальным делать код не нужно. Таким образом потеряется смысл данного кода.
Ой Я туда много лишнего закинул, имелось ввиду только это:
Code:
char monArray[LatestMonID];
// заполняем массив нулями (запрещяем всех монстров)
for (int i = 0; i < LatestMonID; i++)
monArray[i] = 0;
По идее, выбранные в прошлый раз монстры будут просто перезаписываться, если сохранять в отдельную переменную количество отобранных индексов... Выбирать, соответственно, надо случайный элемент массива.
upd. Тогда этот цикл вообще не нужен.
Бред написал... Извиняюсь.
Пусть все остается как есть, я просто опять о разрешенных монстрах стал думать.
Quote:Нет. Этот код вообще отдельно-написанный, и не существует ни в одном из моих плагинов.
Хорошо, я понял.
Quote:Ты используешь заголовочники homm3.h?
Их для 19 студии вообще нужно полностью адаптировать. Правильнее тогда уже использовать заголовочники от Кавалериста (они насыщеннее и работают на новых студиях)
Да... Я что-то слышал о том, что Кавалерист дорабатывает их, но с конечным результатом я не знаком. Можно ссылку пожалуйста?
(This post was last modified: 21.01.2021 17:35 by Raistlin.)
|
|
21.01.2021 16:56 |
|
RoseKavalier
Posts: 118
|
(This post was last modified: 21.01.2021 19:18 by RoseKavalier.)
|
|
21.01.2021 19:18 |
|
Raistlin
Posts: 1349
|
|
21.01.2021 19:59 |
|
igrik
Posts: 2819
|
(21.01.2021 14:52)XEPOMAHT Wrote: Жесткая привязка к номерам монстров. Для поддержки Тифона потребуется:
Жесткая привязка к номерам монстров приведена для показательного примера. И в этом примере очень легко уменьшить кол-во итераций просто прочитав активное кол-во монстров.
Code:
// количество монстров в игре
// тут нужно учесть и Тифон, и Аметист,
// но и не гонять циклы в пустую (поэтому откуда бы считать?)
// int count = 196;
int count = *(int*)0x<адрес 221 монстра в Тифоне>;
Вот только я никак не пойму откуда прочитать это активное (221) кол-во монстров, а не максимальное кол-во (1000). В Тифоне что, нет простого указателя на текущее кол-во задействованных монстров?
game bug fixes extended.dll || My Plugins || My GitHub
|
|
21.01.2021 21:34 |
|
igrik
Posts: 2819
|
Ещё интереснее))
А как тогда скриптеру производить цикл по всем монстрам в скрипте?
Как в плагине производить цикл прохода по всем монстрам в плагине?
Возьмём к примеру часто используемый скрипт: "половинная стоимость существ на 7й день". Как организовать цикл? Сколько итераций производить? 1000? Т.е. 778 итераций в пустую? Как скрипту проверять, что монстра (например id 650) вообще нет, если есть активный монстр с id 666?
Вот я щас потихоньку пилю WoG Scripts II и меня этот вопрос более чем интересует.
game bug fixes extended.dll || My Plugins || My GitHub
|
|
21.01.2021 23:23 |
|