[ГАЙД] Модификация Казаки 3. Основные советы и подсказки.

Discussion in 'Моддинг' started by Mark Kandaurov, Dec 20, 2016.

  1. Mark Kandaurov

    Mark Kandaurov Well-Known Member

    [​IMG]
    Основная информация и подсказки для моддинга Казаков 3


    Специально для группы Cossacks 3 Модификации


    1. Для начала всего и вся, ознакомьтесь со структурой файлов в игре. Папка с игрой расположена в вашей директории Steam. Обычно это: C:\Program Files (x86)\Steam\steamapps\common\Cossacks 3\
    Рекомендую делать бэкапы всех изменяемых файлов, или добавлять модифицированные файлы средствами мод-менеджера.
    Но если случилось непоправимое, вы всегда сможете восстановить файлы игры средствами Steam (ПКМ по игре в библиотеке - Свойства - Локальные файлы - Проверить целостность кэша).
    Это полностью восстановит все измененные игровые файлы.

    2. В независимости от того, что вы собираетесь сделать, вам понадобиться один или несколько инструментов:
    • Во первых это текстовый редактор. Лично я рекомендую Sublime Text. Но вы так же можете использовать Vim, Atom или Notepad++. Это условно бесплатные или полностью бесплатные редакторы, которые сильно упростят вам жизнь. И не только в плане моддинга Казаков 3
    • Во вторых это хороший графический редактор, умеющий в BMP формат. Я рекомендую Adobe Photoshop CC. Так же подойдет GIMP, Pixlr или Paint.NET.
    • В третьих, если вы используете фотошоп, вам пригодиться NVIDIA Texture Tools for Adobe Photoshop. Это расширение поможет открыть и редактировать файлы текстур (.dds).
    • В четвертых, конечно же, софт для 3D-моделирования. Рекомендую использовать 3DS Max. Есть ещё аналоги: Maya, Poser, Blender (бесплатный).

    Разработчики так же не оставили мододелов без внимания, и сделали собственные инструменты для создания модификаций:
    • Во первых это, конечно же, мод-менеджер. Который встроен в игру.
    • Во вторых это игровой редактор, который так же можно найти в папке с игрой.
    • В третьих это плагин для 3DS Max.
    • В четвертых это официальный редактор языка.
    О неофициальных инструментах так же есть смысл сообщить:

    3. Не забывайте про игровой редактор. Он поможет вам протестировать многие вещи в реальном времени, и покажет вам логи игры, и возникшие ошибки.
    Особенно полезно если изменяется графическая составляющая игры.
    Конечно же это также хороший инструмент для редактирования карт.

    4. Включите "логгирование". Делается это в файле cossacks.ini в корневой папке игры. Выставите в нем параметры:
    Code:
    LogFileEnabled = true
    LogFileRoot = true
    LogFileName = cos
    Тоже самое можно сделать и в editor.ini, чтобы сохранялись журналы из редактора.
    Теперь все логи вы сможете найти в папке Logs.

    5. Игровые файлы и сценарии написаны на подобии языка Pascal.
    Прочитайте уроки по этому языку. Научитесь основному синтаксису. Или хотя бы примерно поймите что это такое. Это очень поможет в дальнейшем.

    Ну и закончим Подсказками для начинающих модостроителей:

    - Для лучшего понимания того, что вы делаете будет полезно хорошо знать игру. Понимать различие между игровыми файлами и записями. Вы так же сможете лучше понимать последствия ваших действий и быстро находить ошибки, которые их вызвали.
    - Читайте туториалы по инструментам. Это никогда не помешает.
    - Пробуйте. Всегда пробуйте воплотить в жизнь какую-то идею. Даже если ничего не получается - вы научитесь чему-то новому.
    - Не нужно начинать сразу же с огромных модификаций, которыми вы хотите изменить весь игровой сеттинг, или переделать игру ко всем чертям. Делайте маленькие модификации, даже если они были сделаны до вас. Это поможет избежать кучи проблем в будущем.
    - Скачайте парочку чужих модов, и посмотрите как они сделаны. Возможно вам станет понятны некоторые вещи, и вы сможете использовать это в своих модификациях.
    - Делайте бэкапы своих модов. Много бэкапов. Рано или поздно вы скажете себе спасибо за это.
    - Не следует публиковать сырые версии своих модов. Лучше хорошенько протестируйте всё.
    - Держите рабочее место в чистоте. Помещайте все файлы с модом в различные папки. Не ленитесь давать названия этим папкам.
    - Структуризируйте версии своих модификаций. Если вы обновляете свой мод - давайте ему новый номер версии, и добавьте к этому список изменений.
    - Рекомендую ознакомиться со всеми аспектами графических файлов BMP. Просмотрите туториал по альфа-каналам. Это поможет изменять элементы интерфейса без вреда для игры.

    Прошу смело добавлять или исправлять этот гайд в этой теме.
    Так же жду отзывов, спасибо!
    _____

    Отдельное спасибо Ebel, за гайды на английской ветке форума, которые вдохновили меня на создание этой статьи.
     
    Last edited: Dec 20, 2016
    19ivan92 and Ebel like this.
  2. J0keR

    J0keR Well-Known Member

    о аллах, убери этот позорный дотерский сленг, ты же инструкцию пишешь
     
  3. Mark Kandaurov

    Mark Kandaurov Well-Known Member

    Стесняюсь спросить, причем здесь дота?
    Да и кроме прочего, инструкция или нет - это не обязательно должен быть официальный стиль.

    Но спасибо за замечание.
     
  4. J0keR

    J0keR Well-Known Member

    не стесняйся... при том, что только недодотеры используют такую словарную конструкцию, не имеющую смысловой нагрузки (и как стадо повторяют такие фразы либо за комментатором, либо за стримером)

    нормальный человек не поймет, зачем и какой ему нужен фотошоп, который "должен уметь в графический формат" :)

    "должен уметь в..." "сейчас бы не..." "в 2к16..."
     
  5. Mark Kandaurov

    Mark Kandaurov Well-Known Member

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

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

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

    Doc New Member

    Небольшая инструкция на тему где лежат характеристики юнитов и что с ними делать?

    ВАЖНО: перед любыми правками сделайте себе копию рабочего файла.
    А ещё лучше сделайте свои правки отдельным подключаемым модом. Для этого создайте путь "папка казаков"/mods/"папка вашей модификации"/data/scripts/lib/ и разместите там копии данных файлов .
    В дальнейшем его можно будет включить через modman.exe


    ВАЖНО: после // идет описательная часть строки, которая ан игру не влияет. Комментарии разработчиков и т.д.

    ------------------------- units.scripts---------------------------------------------------

    Начнём с файла: units.scripts по адресу: "папка казаков"/data/scripts/lib/
    Данный файл содержит в себе характеристики всех юнитов игры а так же кучу сопутствующей информации.

    Через поиск ищем: // _unit_InitBase
    разработчики оставили информацию что данный раздел инициализирует все настройки и различия в прототипах юнитов, в зависимости от нации и типа юнита.
    Здесь собраны изначальные настройки для зданий и юнитов в игре.

    например:
    Code:
       procedure SetObjBasePrice(var objbase : TObjBase; food, wood, stone, gold, iron, coal : Integer);
       begin
          objbase.price[gc_resource_type_food] := food;
          objbase.price[gc_resource_type_wood] := wood;
          objbase.price[gc_resource_type_stone] := stone;
          objbase.price[gc_resource_type_gold] := gold;
          objbase.price[gc_resource_type_iron] := iron;
          objbase.price[gc_resource_type_coal] := coal;
       end;
       
    Содержит данные о используемой игрой системе ресурсов, но здесь нам важен сам порядок: еда, дерево, камень, золото, железо, уголь.

    Так же:
    Code:
     procedure SetObjBaseProtection(var objbase : TObjBase; pike, sword, bullet, cannister, arrow, cannonball : Integer);
       begin
          objbase.protection[gc_obj_weapon_kind_pike] := pike;
          objbase.protection[gc_obj_weapon_kind_sword] := sword;
          objbase.protection[gc_obj_weapon_kind_bullet] := bullet;
          objbase.protection[gc_obj_weapon_kind_cannister] := cannister;
          objbase.protection[gc_obj_weapon_kind_arrow] := arrow;
          objbase.protection[gc_obj_weapon_kind_cannonball] := cannonball;
       end;
    Типы используемых атак, порядок так же важен, так как защита юнита идет в таком же порядке: пики, мечи, пули, шрапнель, стрелы, ядра.

    Или:
    Code:
     procedure SetObjBaseWeapon(var objprop : TObjProp; var objbase : TObjBase; index, damage, pause, radiusmin, radiusmax, detectradiusmin, detectradiusmax, kind : Integer; bSearchMinAttackRadius : Boolean);
       begin
          objprop.weapon[index].enabled := True;
          if (damage<>-1) then
          objbase.weapon[index].damage := damage;
          if (radiusmin<>-1) then
          objprop.weapon[index].radiusmin := _misc_PixelsToTiles(radiusmin);
          if (radiusmax<>-1) then
          objbase.weapon[index].radiusmax := _misc_PixelsToTiles(radiusmax);
          if (detectradiusmin<>-1) then
          objprop.weapon[index].detectradiusmin := _misc_PixelsToTiles(detectradiusmin);
          if (detectradiusmax<>-1) then
          objprop.weapon[index].detectradiusmax := _misc_PixelsToTiles(detectradiusmax);
          if (kind<>-1) then
          objprop.weapon[index].kind := kind;
          if (pause<>-1) then
          objbase.weapon[index].pause := _misc_FramesToTime(pause);
          if (bSearchMinAttackRadius) then
          objprop.minattackradius := _unit_GetMinAttackRadiusByObjProp(objprop);
       end;
    Данный код содержит важные для изменения юнита понятия индекса атаки, атака, пауза, минимального и максимального радиуса, радиуса обнаружения минимального и максимального и типа атаки. Запоминаем порядок.

    Для нетерпеливых ищем сразу: // setup юнитов
    Юниты разделены на подразделы:
    // INFANTRY - пехота
    // CAVALRY - кавалерия
    // ARTILLERY - пушки
    // SHIPS - корабли (после кораблей идут уникальные юниты, такие как генерал и ослик)

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

    Возьмем обычного пикинера 17 века:
    // INFANTRY
    'pikeman', 'pikemanpol', 'pikemantur', 'pikemanrus'
    Code:
    'pikeman', 'pikemanpol', 'pikemantur', 'pikemanrus' : begin
                objbase.maxhp := 95;
                SetObjBaseWeapon(objprop, objbase, 0, 8, 0, 35, 100, 0, 100000, gc_obj_weapon_kind_pike, True);
                SetObjBasePrice(objbase, 25, 0, 0, 0, 20, 0);
                SetObjBaseProtection(objbase, 2, 4, 5, 255, 1, 7);
                SetObjBaseMaterialCanKill(objprop, gc_obj_material_body, gc_obj_material_body, gc_obj_material_woodwall, 0, 0, 0);
                SetObjBaseSearchBuildVisionScore(objprop, objbase, 700, 150, 1, 10);
                objprop.bstandground := True;
                objprop.usage := gc_obj_usage_lightinfantry;
                objprop.aiforce := 10;
                objprop.walkintervalfactor := cWalkIntervalInf;
                case nation of
                   'pol' : begin
                      objbase.maxhp := 100;
                      SetObjBaseWeapon(objprop, objbase, 0, 7, default, default, 110, default, default, default, True);
                      SetObjBasePrice(objbase, 45, 1, 0, 0, 0, 0);
                      SetObjBaseProtection(objbase, 0, 2, 0, 0, 0, 0);
                      SetObjBaseSearchBuildVisionScore(objprop, objbase, default, 100, default, default);
                   end;
                   'tur', 'alg' : begin
                      objbase.maxhp := 100;
                      SetObjBaseWeapon(objprop, objbase, 0, 9, default, default, 110, default, default, default, True);
                      SetObjBasePrice(objbase, 55, 0, 0, 0, 2, 0);
                      SetObjBaseProtection(objbase, 0, 2, 0, 0, 0, 0);
                   end;
                   'rus' : begin
                      objbase.maxhp := 90;
                      SetObjBaseWeapon(objprop, objbase, 0, 8, default, 45, 90, default, default, default, True); // c1 damage 9, max range was 100, hp was 100. it have much greater attack speed then in c1
                      SetObjBasePrice(objbase, 55, 0, 0, 0, 15, 0);
                      SetObjBaseProtection(objbase, 2, 3, 4, 150, 1, 4);
                      SetObjBaseSearchBuildVisionScore(objprop, objbase, default, 180, default, default);
                   end;
                end;
    Что мы тут видим:
    Code:
    'pikeman', 'pikemanpol', 'pikemantur', 'pikemanrus'
    собственно и показывает раздел в котором содержатся пикинеры европейские, польский, турецкий (он же алжирский) и русский.
    Code:
    objbase.maxhp := 95;
    Количество здоровья 95.
    Code:
    SetObjBaseWeapon(objprop, objbase, 0, 8, 0, 35, 100, 0, 100000, gc_obj_weapon_kind_pike, True);
    Важная строчка, полное описание атаки: индекс 0, атака 8, пауза 0, минимальный радиус 35, максимальный 100, радиус обнаружения минимальный 0, максимальный 100000, тип оружия пика.
    Например если изменить значение gc_obj_weapon_kind_pike на gc_obj_weapon_kind_sword пикинер будет наносить урон от меча а не пики.
    Code:
    SetObjBasePrice(objbase, 25, 0, 0, 0, 20, 0);
    Сколько стоит, 25 еды и 20 железа.
    Code:
    SetObjBaseProtection(objbase, 2, 2, 5, 255, 1, 7);
    Защита по типам: пики и мечи по 2, пули 5, картечь 255, стрелы 1, ядра 7.
    Code:
    SetObjBaseMaterialCanKill(objprop, gc_obj_material_body, gc_obj_material_body, gc_obj_material_woodwall, 0, 0, 0);
    Кого может атаковать - объекты из плоти (других солдат) и деревянный частокол.
    Code:
    SetObjBaseSearchBuildVisionScore(objprop, objbase, 700, 150, 1, 10);
    Важная строчка, нас интересует второй числовой параметр 150 - время строительства (1 = 0,03 секунды)

    После:
    Code:
    case nation of
    идут отличия пикинеров какой либо конкретной нации, в нашем случае
    'pol' - поляки, 'tur', 'alg' -турки и алжир, 'rus' - русские.
    Например мы видим что польские, турецкие/алжирские пикинеры не имеют начальной брони, Польский пикинер строится на 1/3 быстрее (100. а не 150) и у всех здоровье отличное от европейского пикинера.

    В дальнейшем все идет так же - общий раздел юнита и частности отдельных наций.

    Так же у отдельных юнитов будут встречаться строчки, характерные только для них, например:
    после легкой пехоты 'lightinfantry' идет сразу переменная if (bmercenary) then, которая показывает характеристики наемной легкой пехоты. (Так же у рундашира, лучника, сечевого казака и драгуна)

    Для наемников, офицеров и некоторых юнитов характерна строчка
    Code:
    objprop.consume[gc_resource_type_gold] := 3;
    которая показывает сколько ресурса (в данном случае золота) расходует данный юнит.

    У стрелков есть строчки:
    Code:
                  objprop.weapon[weapInd].cost[gc_resource_type_iron] := 3;
                  objprop.weapon[weapInd].cost[gc_resource_type_coal] := 3;
    Которые показывают расход железа и угля на выстрел (в данном случае по 3 угля и железа).
    У лучников:
    Code:
                objbase.weapon[0].dispertion := _misc_PixelsToTiles(250);
    которая отвечает за разброс стрел (Можете выключить ее (//) и посмотреть в каких терминаторов превратятся обычные алжирские лучники. )
     
    Last edited: Dec 20, 2016
  7. Doc

    Doc New Member

    Продолжим:

    ------------------------- country.scripts---------------------------------------------------

    Следующий файл: country.scripts по адресу: "папка казаков"/data/scripts/lib/
    Данный файл содержит в себе улучшения всех юнитов, зданий (в том числе улучшения а академии, кузнице и т.п.) игры а так же кучу сопутствующей информации.

    Ищем строчку: // _country_InitUnitsUpgrades
    В данном разделе находится информация по используемым в улучшениях юнитов типам оружия и защиты.
    Code:
    procedure _country_InitUnitsUpgrades(var country : TCountry; var ind, linkind : Integer);
    begin
       const bAddIfNotExist = True;
       const cTrue = True; // for better formating and reading
       const ctypeDamagePike = 0;
       const ctypeDamageSword = 1;
       const ctypeDamageBullet = 2;
       const ctypeProtection = 3;
       const ctypeProtectionOnlyPikeArrow = 4;
       const ctypeProtectionOnlySword = 5;
    Это значит что для юнитов применяются следующие типы улучшений:
    Урон от пики
    Урон от меча
    Урон от пули
    Защиты (пика, меч, стрела) - самый распространенный тип защиты.
    Защиты только от пик и стрел
    Защиты только от меча
    В данном случае данный код нужен не сам по себе, а в связке с другим.
    Смотрим чуть дальше:
    Code:
    begin
          var j : Integer;
          for j:=0 to 5 do
          begin
             if (upgstruct.value[j]<>0) then
             begin
                var iupgtype : Integer = gc_upg_type_none;
                var iupgtype2 : Integer = 1;
                var iparam1, iparam2, iparam3 : Integer;
                case upgradetype of
                   ctypeDamagePike : begin
                      iupgtype := gc_upg_type_damage;
                      iparam1 := gc_obj_weapon_kind_pike;
                   end;
                   ctypeDamageSword : begin
                      iupgtype := gc_upg_type_damage;
                      iparam1 := gc_obj_weapon_kind_sword;
                   end;
                   ctypeDamageBullet : begin
                      iupgtype := gc_upg_type_damage;
                      iparam1 := gc_obj_weapon_kind_bullet;
                   end;
                   ctypeProtection : begin
                      iupgtype := gc_upg_type_protection;
                      iparam1 := gc_obj_weapon_kind_pike;
                      iparam2 := gc_obj_weapon_kind_sword;
                      iparam3 := gc_obj_weapon_kind_arrow;
                      iupgtype2 := 2;
                   end;
                   ctypeProtectionOnlyPikeArrow : begin
                      iupgtype := gc_upg_type_protection;
                      iparam1 := gc_obj_weapon_kind_pike;
                      iparam3 := gc_obj_weapon_kind_arrow;
                      iupgtype2 := 2;
                   end;
                   ctypeProtectionOnlySword : begin
                      iupgtype := gc_upg_type_protection;
                      iparam2 := gc_obj_weapon_kind_sword;
                      iupgtype2 := 2;
                   end;
                   else
                   ErrorLog('AddUpgradePack : Unknown type');
                end;
                _country_AddUpgradeWithAccessControl(country, upgstruct.place+'.'+upgstruct.member+'.'+IntToStr(iupgtype2)+'.'+IntToStr(j+1), j+2, tooltiptype, iupgtype, upgstruct.value[j], (j=0) and bEnabled, 500, x, y, ind, upgstruct.food[j], upgstruct.wood[j], upgstruct.stone[j], upgstruct.gold[j], upgstruct.iron[j], upgstruct.coal[j], bAddIfNotExist, iparam1, iparam2, iparam3, upgstruct.member, '', '', '', '', '', '', '', '', '', True, upgstruct.req[0], upgstruct.req[1], upgstruct.req[2], upgstruct.req[3], upgstruct.req[4], upgstruct.req[5], '', '');
                if (j<5) and (upgstruct.value[j+1]<>0) then
                _country_AddUpgradeLink(country, upgstruct.place+'.'+upgstruct.member+'.'+IntToStr(iupgtype2)+'.'+IntToStr(j+1), upgstruct.place+'.'+upgstruct.member+'.'+IntToStr(iupgtype2)+'.'+IntToStr(j+2), linkind);
             end;
          end;
       end;
    Вот и полное раскрытие информации по улучшениям.
    Например как устроена строчка защиты:
    Это наиболее используемый тип защиты.
    Code:
    ctypeProtection : begin
                      iupgtype := gc_upg_type_protection;
                      iparam1 := gc_obj_weapon_kind_pike;
                      iparam2 := gc_obj_weapon_kind_sword;
                      iparam3 := gc_obj_weapon_kind_arrow;
                      iupgtype2 := 2;
    Броня от пик, мечей и стрел. 3 строчки каждая отвечает за определенный тип защиты.

    Все нам понадобится для понимания в дальнейшем работы данной системы.

    Самые нетерпеливые идут сразу сюда: // barracks
    Типы юнитов по подразделам разделены почти так же как и в units.scripts, но количество подразделов гораздо больше, так как улучшения разделены по векам и для уникальных юнитов выделены в отдельные подразделы.
    // barracks - улучшения юнитов в бараках.
    // barracks 18 century - улучшения юнитов в бараках 18 века.
    // stables - улучшения юнитов в конюшнях.
    // cavalry 18 century - улучшения юнитов в конюшнях 18 века.
    // barrack 18 century unique units - улучшения уникальных юнитов в бараках.
    // stable unique units - улучшения уникальных юнитов в конюшнях.

    Возьмемся например за пикинеров 17 века:
    // barracks
    Самые первые:
    Code:
    case cid of
          _rus : member := 'pikemanrus';
          _ukr : member := '';
          _pol : member := 'pikemanpol';
          _tur : member := 'pikemantur';
          _alg : member := 'pikemantur';
          else
          member := 'pikeman';
       end;
       if (member<>'') then
       begin
          case cid of
             _aus : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 200, 50, True, 2, 1300, 300, True, 3, 3600, 450, True, 1, 7200, 1850, True, 2, 16030, 2000, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
             _fra : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 100, 25, True, 2, 1400, 325, True, 3, 4600, 650, True, 2, 6200, 1650, True, 1, 15300, 2075, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
             _eng : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 200, 50, True, 2, 1250, 310, True, 4, 3900, 650, True, 1, 7200, 1850, True, 1, 16030, 2000, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
             _spa : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 200, 50, True, 2, 1300, 300, True, 3, 3600, 450, True, 1, 7200, 1850, True, 2, 16030, 2000, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
             _rus : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 200, 50, True, 2, 1300, 300, True, 3, 3600, 450, True, 1, 7200, 1850, True, 2, 16030, 2000, True, 0, 0, 0, blacksmith, ''); // Pik_rus
             _ukr : ;
             _pol : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 500, 50, True, 2, 1400, 100, True, 3, 3200, 450, True, 1, 8200, 2220, True, 2, 15030, 1800, True, 0, 0, 0, blacksmith, ''); // Pikiner_polan
             _swe : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 100, 90, True, 2, 300, 450, True, 3, 4600, 300, True, 1, 9200, 1250, True, 2, 14030, 2600, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
             _pru : SetUpgStructFoodGold(upgstruct, upgplace, member, 2, 3600, 450, True, 2, 1300, 300, True, 2, 200, 50, True, 1, 6800, 1950, True, 2, 15030, 2300, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
             _ven : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 200, 50, True, 2, 1300, 300, True, 3, 3600, 450, True, 1, 7200, 1850, True, 2, 16030, 2000, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
             _tur : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 200, 50, True, 2, 600, 300, True, 3, 1200, 450, True, 1, 2200, 1850, True, 2, 16030, 2000, True, 0, 0, 0, blacksmith, ''); // Pikiner_turki
             _alg : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 200, 50, True, 2, 600, 300, True, 3, 1200, 450, True, 1, 2200, 1850, True, 2, 16030, 2000, True, 0, 0, 0, blacksmith, ''); // Pikiner_turki
             _den : SetUpgStructFoodGold(upgstruct, upgplace, member, 2, 3600, 450, True, 2, 1300, 300, True, 2, 200, 50, True, 1, 6800, 1950, True, 2, 15030, 2300, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
             _net : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 900, 150, True, 2, 700, 400, True, 3, 3100, 250, True, 1, 6700, 1950, True, 2, 16030, 2000, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
          end;
          AddUpgradePack(country, upgstruct, ctypeDamagePike, gc_upg_tooltiptype_infdmg, 0, 1, True, ind, linkind);
          case cid of
             _aus : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 150, 50, True, 2, 900, 175, True, 3, 4500, 300, True, 1, 9005, 507, True, 2, 18010, 3050, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
             _fra : SetUpgStructFoodGold(upgstruct, upgplace, member, 2, 350, 90, True, 1, 1000, 135, True, 3, 4200, 500, True, 1, 11075, 310, True, 2, 15050, 3050, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
             _eng : SetUpgStructFoodGold(upgstruct, upgplace, member, 2, 990, 50, True, 1, 200, 175, True, 3, 4500, 300, True, 1, 9005, 507, True, 2, 17010, 3050, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
             _spa : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 150, 50, True, 2, 900, 175, True, 3, 4500, 300, True, 1, 9005, 507, True, 2, 18010, 3050, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
             _rus : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 150, 50, True, 2, 900, 175, True, 3, 4500, 300, True, 1, 9005, 507, True, 2, 18010, 3050, True, 0, 0, 0, blacksmith, ''); // Pik_rus
             _ukr : ;
             _pol : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 250, 75, True, 2, 800, 150, True, 3, 3500, 225, True, 3, 9005, 407, True, 9, 19010, 2975, True, 0, 0, 0, blacksmith, ''); // Pikiner_polan
             _swe : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 350, 50, True, 2, 700, 275, True, 3, 2500, 200, True, 1, 13005, 997, True, 2, 16010, 2550, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
             _pru : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 175, 40, True, 1, 990, 275, True, 4, 4700, 280, True, 1, 9505, 707, True, 2, 17510, 2950, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
             _ven : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 150, 50, True, 2, 900, 175, True, 3, 4500, 300, True, 1, 9005, 507, True, 2, 18010, 3050, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
             _tur : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 150, 50, True, 2, 900, 175, True, 3, 4500, 300, True, 1, 9005, 507, True, 2, 18010, 3050, True, 0, 0, 0, blacksmith, ''); // Pikiner_turki
             _alg : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 150, 50, True, 2, 900, 175, True, 3, 4500, 300, True, 1, 9005, 507, True, 2, 18010, 3050, True, 0, 0, 0, blacksmith, ''); // Pikiner_turki
             _den : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 175, 40, True, 1, 990, 275, True, 4, 4700, 280, True, 1, 9005, 707, True, 2, 17510, 2950, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
             _net : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 250, 150, True, 2, 800, 275, True, 3, 4200, 100, True, 1, 9305, 707, True, 2, 17890, 2850, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
          end;
          var tmptype : Integer = ctypeProtection;
          if (pol) then // poland pikeman got unique, upgrade mechanic. he upgrade protection from pike and arrow. and only last upgrade, improve protection from sword
          tmptype := ctypeProtectionOnlyPikeArrow;
          AddUpgradePack(country, upgstruct, tmptype, gc_upg_tooltiptype_infdef, 0, 2, True, ind, linkind);
          if (pol) then
          begin
             country.upgrade[ind-1].iarrparam1[0] := gc_obj_weapon_kind_none;
             country.upgrade[ind-1].iarrparam1[1] := gc_obj_weapon_kind_sword;
             country.upgrade[ind-1].iarrparam1[2] := gc_obj_weapon_kind_none;
          end;
       end;

    ВНИМАНИЕ: меняем все аккуратно, стараясь не допустить отсутствие пробелов или потерю запятых - иначе ничего не будет работать. Сохраняйте рабочие копии файла почаще.

    Что мы тут видим:
    Code:
    _aus : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 200, 50, True, 2, 1300, 300, True, 3, 3600, 450, True, 1, 7200, 1850, True, 2, 16030, 2000, True, 0, 0, 0, blacksmith, ''); // Pikiner_evro
    Каждая строчка начинается с буквенного обозначения страны, в данном случае _aus - Австрия, Дальше идет обозначение ресурсов используемых для улучшения (SetUpgStructFoodGold) еда и золото. Дальше сами значения по уровням улучшений:
    , 1, 200, 50, - улучшение атаки на 1 за 200 еды и 50 золота (второй уровень)
    , 2, 1300, 300, - улучшение атаки на 2 за 1300 еды и 300 золота (третий уровень) и так далее.
    в конце строчки будет обозначение здания, необходимого для возможности проведения улучшений, в данном случае blacksmith (кузница).
    И так для каждого пикинера каждой страны, кроме украинцев, у них нет пикинера потому строчка выглядит так:
    Code:
    _ukr : ;
    Дальше видим следующую строчку:
    Code:
    AddUpgradePack(country, upgstruct, ctypeDamagePike, gc_upg_tooltiptype_infdmg, 0, 1, True, ind, linkind);
    В данном случае нас интересует что для улучшения всех вышеперечисленных юнитов используется улучшения атаки пикой: ctypeDamagePike. Цифры: 0, 1, обозначают местоположение улучшения для юнита: нулевой ряд, 1 строчка (не нулевая строчка, на нулевой сам пикинер в бараках).

    Само собой, если мы изменили для какого либо юнита тип атаки в units.scripts то улучшения не будут работать пока мы не изменим тип атаки, применяемый в улучшениях.
    Ниже идут строчки для защиты нашего многострадального пикинера, принцип тот же.
    А вот потом начинается самое интересное:
    Code:
    var tmptype : Integer = ctypeProtection;
          if (pol) then // poland pikeman got unique, upgrade mechanic. he upgrade protection from pike and arrow. and only last upgrade, improve protection from sword
          tmptype := ctypeProtectionOnlyPikeArrow;
          AddUpgradePack(country, upgstruct, tmptype, gc_upg_tooltiptype_infdef, 0, 2, True, ind, linkind);
          if (pol) then
          begin
             country.upgrade[ind-1].iarrparam1[0] := gc_obj_weapon_kind_none;
             country.upgrade[ind-1].iarrparam1[1] := gc_obj_weapon_kind_sword;
             country.upgrade[ind-1].iarrparam1[2] := gc_obj_weapon_kind_none;
          end;
    Разработчики разъясняют:
    // poland pikeman got unique, upgrade mechanic. he upgrade protection from pike and arrow. and only last upgrade, improve protection from sword
    // Польский пикинер имеет уникальную механику улучшений, он улучшает защиту против пик и стрел, и только последнее улучшение повышается защиту против мечей.
    Что тут для нас важного:
    Code:
    var tmptype : Integer = ctypeProtection;
    переключаемый тип защиты - защита против пик, мечей и стрел.
    Code:
    if (pol) then
    переключатель - в данном случае польский пикинер.
    Code:
    tmptype := ctypeProtectionOnlyPikeArrow;
    используемый после переключения тип защиты - защита против пик и стрел.
    И самое вкусное:
    Code:
             country.upgrade[ind-1].iarrparam1[0] := gc_obj_weapon_kind_none;
             country.upgrade[ind-1].iarrparam1[1] := gc_obj_weapon_kind_sword;
             country.upgrade[ind-1].iarrparam1[2] := gc_obj_weapon_kind_none;
    Из защиты вычитаются строчки первая (надеюсь вы читали раздел для ознакомления?)- защита от пик и третья - защита от стрел, остается только вторая - защита от мечей.
    Например мы захотели что бы наши юниты на последнем уровне улучшения своей защиты улучшали ее только против только стрел. Делаем так:
    Code:
          AddUpgradePack(country, upgstruct, ctypeProtection, тут данные вашей строчки);
             country.upgrade[ind-1].iarrparam1[0] := gc_obj_weapon_kind_none;
             country.upgrade[ind-1].iarrparam1[1] := gc_obj_weapon_kind_none;
             country.upgrade[ind-1].iarrparam1[2] := gc_obj_weapon_kind_arrow;
    
    В данном случае мы вычитаем защиту от пик и мечей из защиты (ctypeProtection) от пик, мечей и стрел.
    ВАЖНО: вычитать можно те строки, которые содержатся в данной защите!
     
    Last edited: Dec 21, 2016
  8. Doc

    Doc New Member

    Идем дальше:
    В основном все однотипно но вот мы доходим до мушкетеров (member := 'musketeer';) и видим следующее:
    Code:
    case cid of
          _aus : member := 'musketeeraus';
          _spa : member := 'musketeerspa';
          _rus : member := 'strelet';
          _ukr : member := 'serdiuk';
          _pol : member := 'musketeerpol';
          _tur : member := 'jannisary';
          _alg : member := '';
          _net : member := 'musketeernet';
          else
          member := 'musketeer';
       end;
       if (member<>'') then
       begin
          var posx : Integer = 2;
          if (cid=_ukr) then
          posx := 0;
          case cid of
             _aus : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 2000, 100, True, 1, 1000, 300, True, 2, 500, 700, True, 0, 0, 0, True, 0, 0, 0, True, 0, 0, 0, blacksmith, ''); // Mushketer_avstr
             _fra : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 100, 50, True, 2, 3000, 500, True, 3, 2500, 750, True, 0, 0, 0, True, 0, 0, 0, True, 0, 0, 0, blacksmith, ''); // Mushketer_ev
             _eng : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 1900, 150, True, 1, 1000, 300, True, 2, 500, 700, True, 0, 0, 0, True, 0, 0, 0, True, 0, 0, 0, blacksmith, ''); // Mushketer_ev
             _spa : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 2000, 100, True, 1, 1000, 300, True, 2, 500, 700, True, 0, 0, 0, True, 0, 0, 0, True, 0, 0, 0, blacksmith, ''); // Strelec_Spain
             _rus : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 2000, 100, True, 1, 1000, 300, True, 2, 500, 700, True, 0, 0, 0, True, 0, 0, 0, True, 0, 0, 0, blacksmith, ''); // Strelec
             //_ukr : SetUpgStructFoodGoldIronCoal(upgstruct, upgplace, member, 2, 22000, 800, 0, 0, True, 3, 32400, 5800, 0, 0, True, 4, 42010, 6800, 0, 0, True, 5, 52300, 1800, 7400, 0, True, 6, 45000, 300, 14500, 0, True, 10, 62400, 0, 0, 39200, blacksmith, ''); // Kozacki_Strelec
             _ukr : SetUpgStructFoodGoldIronCoal(upgstruct, upgplace, member, 2, 22000, 800, 0, 0, True, 3, 32400, 5800, 0, 0, True, 4, 42010, 6800, 0, 0, True, 5, 52300, 1800, 7400, 0, True, 6, 45000, 300, 14500, 0, True, 0, 0, 0, 0, 0, blacksmith, ''); // C3 changes (remove last upg to damage and protection
             _pol : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 500, 125, True, 1, 1250, 275, True, 2, 2500, 650, True, 0, 0, 0, True, 0, 0, 0, True, 0, 0, 0, blacksmith, ''); // Mushketer_polsha
             _swe : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 1000, 200, True, 1, 2000, 200, True, 2, 100, 200, True, 0, 0, 0, True, 0, 0, 0, True, 0, 0, 0, blacksmith, ''); // Mushketer_ev
             _pru : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 2000, 100, True, 1, 1000, 300, True, 2, 500, 700, True, 0, 0, 0, True, 0, 0, 0, True, 0, 0, 0, blacksmith, ''); // Mushketer_ev
             _ven : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 2000, 100, True, 1, 1000, 300, True, 2, 500, 700, True, 0, 0, 0, True, 0, 0, 0, True, 0, 0, 0, blacksmith, ''); // Mushketer_ev
             _tur : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 2000, 100, True, 1, 1000, 300, True, 2, 500, 700, True, 0, 0, 0, True, 0, 0, 0, True, 0, 0, 0, blacksmith, ''); // Ianithar
             _alg : ;
             _den : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 2000, 100, True, 1, 1000, 300, True, 2, 500, 700, True, 0, 0, 0, True, 0, 0, 0, True, 0, 0, 0, blacksmith, ''); // Mushketer_ev
             _net : SetUpgStructFoodGold(upgstruct, upgplace, member, 1, 2000, 100, True, 1, 1000, 300, True, 2, 500, 700, True, 0, 0, 0, True, 0, 0, 0, True, 0, 0, 0, blacksmith, ''); // Mushketer_ev
          end;
          AddUpgradePack(country, upgstruct, ctypeDamageBullet, gc_upg_tooltiptype_shooterdmg, posx, 1, True, ind, linkind);
          case cid of
             _aus : SetUpgStructFoodGoldIron(upgstruct, upgplace, member, 1, 170, 50, 100, True, 2, 405, 150, 200, True, 3, 3570, 100, 350, True, 1, 1556, 1350, 100, True, 1, 1060, 2050, 400, True, 1, 5700, 1350, 700, blacksmith, ''); // Mushketer_avstr
             _fra : SetUpgStructFoodGoldIron(upgstruct, upgplace, member, 2, 200, 75, 200, True, 2, 705, 250, 250, True, 2, 4560, 300, 450, True, 1, 1556, 1350, 100, True, 1, 1060, 2050, 400, True, 1, 5700, 1350, 700, blacksmith, ''); // Mushketer_ev
             _eng : SetUpgStructFoodGoldIron(upgstruct, upgplace, member, 1, 220, 50, 100, True, 2, 505, 140, 200, True, 3, 3670, 100, 350, True, 1, 1000, 1720, 100, True, 1, 2060, 1900, 400, True, 1, 5900, 1150, 700, blacksmith, ''); // Mushketer_ev
             _spa : SetUpgStructFoodGoldIron(upgstruct, upgplace, member, 1, 170, 50, 100, True, 2, 405, 150, 200, True, 3, 3570, 100, 350, True, 1, 1556, 1350, 100, True, 1, 1060, 2050, 400, True, 1, 5700, 1350, 700, blacksmith, ''); // Strelec_Spain
             _rus : SetUpgStructFoodGoldIron(upgstruct, upgplace, member, 1, 170, 50, 100, True, 2, 405, 150, 200, True, 3, 3570, 100, 350, True, 1, 1556, 1350, 100, True, 1, 1060, 2050, 400, True, 1, 5700, 1350, 700, blacksmith, ''); // Strelec
             //_ukr : SetUpgStructFoodGoldIronCoal(upgstruct, upgplace, member, 1, 3706, 0, 2350, 0, True, 2, 12060, 0, 7850, 0, True, 3, 36706, 0, 14000, 0, True, 4, 36706, 0, 22350, 0, True, 5, 37060, 0, 34350, 0, True, 6, 55706, 0, 0, 51350, blacksmith, ''); // Kozacki_Strelec
             _ukr : SetUpgStructFoodGoldIronCoal(upgstruct, upgplace, member, 1, 3706, 0, 2350, 0, True, 2, 12060, 0, 7850, 0, True, 3, 36706, 0, 14000, 0, True, 4, 36706, 0, 22350, 0, True, 5, 37060, 0, 34350, 0, True, 0, 0, 0, 0, 0, blacksmith, ''); // C3 changes (remove last upg to damage and protection
             _pol : SetUpgStructFoodGoldIron(upgstruct, upgplace, member, 1, 125, 150, 100, True, 2, 375, 100, 200, True, 3, 2570, 300, 450, True, 1, 2556, 1150, 400, True, 1, 3060, 1550, 100, True, 1, 3700, 1850, 600, blacksmith, ''); // Mushketer_polsha
             _swe : SetUpgStructFoodGoldIron(upgstruct, upgplace, member, 1, 450, 550, 300, True, 2, 405, 150, 20, True, 3, 3570, 100, 290, True, 1, 1956, 1250, 700, True, 1, 1660, 1750, 400, True, 1, 4700, 1750, 100, blacksmith, ''); // Mushketer_ev
             _pru : SetUpgStructFoodGoldIron(upgstruct, upgplace, member, 1, 170, 50, 100, True, 2, 405, 150, 200, True, 3, 3570, 100, 350, True, 1, 1556, 1350, 100, True, 1, 1060, 2050, 400, True, 1, 5700, 1350, 700, blacksmith, ''); // Mushketer_ev
             _ven : SetUpgStructFoodGoldIron(upgstruct, upgplace, member, 1, 170, 50, 100, True, 2, 405, 150, 200, True, 3, 3570, 100, 350, True, 1, 1556, 1350, 100, True, 1, 1060, 2050, 400, True, 1, 5700, 1350, 700, blacksmith, ''); // Mushketer_ev
             _tur : SetUpgStructFoodGoldIron(upgstruct, upgplace, member, 1, 170, 50, 100, True, 2, 405, 150, 200, True, 3, 3570, 100, 350, True, 1, 1556, 1350, 100, True, 1, 1060, 2050, 400, True, 1, 5700, 1350, 700, blacksmith, ''); // Ianithar
             _alg : ;
             _den : SetUpgStructFoodGoldIron(upgstruct, upgplace, member, 1, 170, 50, 100, True, 2, 405, 150, 200, True, 3, 3570, 100, 350, True, 1, 1556, 1350, 100, True, 1, 1060, 2050, 400, True, 1, 5700, 1350, 700, blacksmith, ''); // Mushketer_ev
             _net : SetUpgStructFoodGoldIron(upgstruct, upgplace, member, 1, 170, 50, 100, True, 2, 405, 150, 200, True, 3, 3570, 100, 350, True, 1, 1556, 1350, 100, True, 1, 1060, 2050, 400, True, 1, 5700, 1350, 700, blacksmith, ''); // Mushketer_ev
          end;
          AddUpgradePack(country, upgstruct, ctypeProtection, gc_upg_tooltiptype_infdef, posx, 2, True, ind, linkind);
       end;
    Различия:
    Code:
    var posx : Integer = 2;
          if (cid=_ukr) then
          posx := 0;
    Code:
          AddUpgradePack(country, upgstruct, ctypeDamageBullet, gc_upg_tooltiptype_shooterdmg, posx, 1, True, ind, linkind);
    Это переключатель, который показывает, что для Украины (cid=_ukr) улучшения сердюка будут располагаться в нулевом столбце (posx := 0) а не во втором (Integer = 2), так как у Украины нет пикинеров и сердюк расположен в нулевом столбце.
    Так же будет и для других юнитов с отличным от используемого массива положением.

    Хорошо идем дальше до гренадеров: member := 'grenadier'

    Code:
             AddUpgradePack(country, upgstruct, ctypeDamagePike, gc_upg_tooltiptype_infdmg, 3, 1, True, ind, linkind);
             // make last attack upgrade to increase grenade damage
             country.upgrade[ind-1].tooltiptype := gc_upg_tooltiptype_grenadedmg;
             country.upgrade[ind-1].iarrparam1[0] := gc_obj_weapon_kind_mortarball;

    Разработчики пишут:
    // make last attack upgrade to increase grenade damage
    // последний апгрейд атаки улучшает урон от гранат.

    Тот же принцип, что и с польским пикинером, только для атаки.
    Само собой улучшать таким образом можно только тот тип атаки, который у юнита уже есть.

    Дальше идем до кода для казаков реестровых и донских, мамлюков, сипахов и затесавшегося туда польского рейтара (ищем: _rus : member := 'cossackdon';).
    Что тут интересного, разработчики показывают новый тип переключателя:
    //var cUpgType : Integer = _misc_SwitchInt(ctypeDamagePike, ctypeDamageSword, (cid=_pol));
    Что он делает, ну если бы был включен, переключает для польского рейтара((cid=_pol)) улучшения атаки с используемого типа пики на тип мечи.
    Например заменим польскому рейтару (это который легкий с сабелькой) в units.scripts атаку с пики на меч. Добавим в раздел где он делит соседство с мамлюками и козаками на замену:
    Code:
          AddUpgradePack(country, upgstruct, ctypeDamagePike, gc_upg_tooltiptype_infdmg, posx, 1, True, ind, linkind);
    такие строчки:
    Code:
    var cUpgType : Integer = _misc_SwitchInt(ctypeDamagePike, ctypeDamageSword, (cid=_pol));
          AddUpgradePack(country, upgstruct, cUpgType, gc_upg_tooltiptype_infdmg, posx, 1, True, ind, linkind);
    Что получим на выходе - мамлюки, сипахи и казаки будут по прежнему улучшать атаку пикой, а вот у польского рейтара начнут работать улучшения на атаку мечом.
    Принцип прост: первый тип улучшения атаки: ctypeDamagePike заменяется на второй ctypeDamageSword для указанного (cid=_pol) юнита. В самом AddUpgradePack заменяем тип атаки с ctypeDamagePike, как ранее использовавшийся для всех на cUpgType - переключаемый.

    Ну и последнее для юнитов:
    Что же делать если мы хотим добавить свой тип защиты для дальнейшего использования?
    Идем по адресу: // _country_InitUnitsUpgrades
    Добавляем после кода:
    Code:
    procedure _country_InitUnitsUpgrades(var country : TCountry; var ind, linkind : Integer);
    begin
       const bAddIfNotExist = True;
       const cTrue = True; // for better formating and reading
       const ctypeDamagePike = 0;
       const ctypeDamageSword = 1;
       const ctypeDamageBullet = 2;
       const ctypeProtection = 3;
       const ctypeProtectionOnlyPikeArrow = 4;
       const ctypeProtectionOnlySword = 5;
    Свою строчку, например - защиту только от стрел:
    Code:
    const ctypeProtectionOnlyАrrow = 6
    Идем ниже:
    procedure AddUpgradePack(var country : TCountry; upgstruct : TUpgStruct; upgradetype, tooltiptype, x, y : Integer; bEnabled : Boolean; var ind, linkind : Integer);
    Добавляем после:
    Code:
    begin
          var j : Integer;
          for j:=0 to 5 do
          begin
             if (upgstruct.value[j]<>0) then
             begin
                var iupgtype : Integer = gc_upg_type_none;
                var iupgtype2 : Integer = 1;
                var iparam1, iparam2, iparam3 : Integer;
                case upgradetype of
                   ctypeDamagePike : begin
                      iupgtype := gc_upg_type_damage;
                      iparam1 := gc_obj_weapon_kind_pike;
                   end;
                   ctypeDamageSword : begin
                      iupgtype := gc_upg_type_damage;
                      iparam1 := gc_obj_weapon_kind_sword;
                   end;
                   ctypeDamageBullet : begin
                      iupgtype := gc_upg_type_damage;
                      iparam1 := gc_obj_weapon_kind_bullet;
                   end;
                   ctypeProtection : begin
                      iupgtype := gc_upg_type_protection;
                      iparam1 := gc_obj_weapon_kind_pike;
                      iparam2 := gc_obj_weapon_kind_sword;
                      iparam3 := gc_obj_weapon_kind_arrow;
                      iupgtype2 := 2;
                   end;
                   ctypeProtectionOnlyPikeArrow : begin
                      iupgtype := gc_upg_type_protection;
                      iparam1 := gc_obj_weapon_kind_pike;
                      iparam3 := gc_obj_weapon_kind_arrow;
                      iupgtype2 := 2;
                   end;
                   ctypeProtectionOnlySword : begin
                      iupgtype := gc_upg_type_protection;
                      iparam2 := gc_obj_weapon_kind_sword;
                      iupgtype2 := 2;
                   end;
                   ctypeProtectionOnlySwordPike : begin
                      iupgtype := gc_upg_type_protection;
                      iparam1 := gc_obj_weapon_kind_pike;
                      iparam2 := gc_obj_weapon_kind_sword;
                      iupgtype2 := 2;
                   end;
    Свою расшифровку типа используемой брони:
    Code:
                   ctypeProtectionOnlyArrow : begin
                      iupgtype := gc_upg_type_protection;
                      iparam3 := gc_obj_weapon_kind_arrow;
                      iupgtype2 := 2;
                   end
    И в начале этого кода добавляем 6 вместо 5, так как у нас добавился новый тип защиты.
    Все, теперь вы можете выдавать юнитам улучшения защиты только против стрел.
     
    Last edited: Dec 21, 2016
    J0keR likes this.
  9. qishii

    qishii New Member

    А как менять файл с расширением " PALETTE "?
     
    Vova Dumanskiy likes this.
  10. Mark Kandaurov

    Mark Kandaurov Well-Known Member

    Вручную, в текстовом редакторе.
    Чтобы понимать как именно его менять, можно зайти в Игровой редактор. Там есть меню с палитрами и таблица.

    Могу подробнее описать, но только позже.
     
  11. qishii

    qishii New Member

    Спасибо;)
     
  12. Андрей

    Андрей New Member

    Mark Kandaurov подскажи где писать логику миссии?
     
  13. Mark Kandaurov

    Mark Kandaurov Well-Known Member

    Лично я не знаю. Однажды пытался сделать хотя бы что то простое, но в редакторе черт ногу сломит, а гайдов от разработчиков пока нету.
     
  14. M.K.даёте обещаный ПЫСами RPG!:D
     
  15. Demoul

    Demoul New Member

    Можно ли сделать так что бы при переходе в 18 век блокировались юниты 17-го века?