Community Imperial: Гарнизонный скрипт. Перезапуск темы (Medieval 2: Total War) - Сообщество Империал

bitterhowl

Гарнизонный скрипт. Перезапуск темы (Medieval 2: Total War)

Актуальные сведения по написанию гарнизонных скриптов по состоянию на 2021 год
Theme created: 25 January 2021, 01:42 · Author: bitterhowl
  • 4 Pages
  • 1
  • 2
  • 3
  • 4
 1 
 bitterhowl
  • Imperial
Imperial
El Compilator

Date: 25 January 2021, 01:42

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

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

Первый вариант срабатывания – в момент, когда поселение только что выбрано для осады и стек осаждающего войска начинает путь к нему.
monitor_event Transgression TransgressionName = TC_INSTIGATE_SIEGE
В этом случае гарнизонные юниты появляются еще до того, как поселение получит изображение осажденного на страткарте. Юниты гарнизона будут видны во время осады и число солдат в добавленных юнитах будет уменьшаться, как и у прочих отрядов в осажденном поселении. При этом, если скрипт написан и для случаев ИИ против ИИ, атакующая фракция ИИ будет видеть эти юниты и учитывать их наличие при планировании штурма.

Более распространенный вариант прописи – срабатывание в момент, когда поселение уже осаждено и атакующая сторона выбирает действие «атаковать».
monitor_event GeneralAssaultsResidence CharacterIsLocal

В этом случае для пользователя открывается меню атаки поселения, где можно выбрать "автобой", "бой на карте", либо "продолжение осады". И в этот момент в поселении появляется гарнизон. Доступны ли такие варианты выбора в случае ИИ против ИИ – наверняка неизвестно, но с учетом третьего (см. ниже) механизма гарнизонного скрипта – видимо нет. Таким образом, ИИ не сможет отозвать штурм и продолжить осаду, если появление гарнизона меняет соотношение сил не в пользу атакующих, как это может сделать игрок, увидев появившийся гарнизон. Что делает крайне сомнительным применение варианта "ИИ против ИИ".

В модах вы можете встретить боле детальный вариант данной прописи, когда учитывается случай нападения на осаждающую армию извне
monitor_event GeneralAssaultsGeneral not CharacterIsLocal
and TargetFactionIsLocal

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

Также есть вариант вылазки гарнизона против осаждающих
monitor_event UngarrisonedSettlement SettlementName Paris
and I_SettlementUnderSiege Paris

В целом, подобная детализация строго на любителя.

Третий вариант прописи скрипта – появление юнитов в гарнизоне в момент, когда игрок выбирает в меню атаки осажденного поселения вариант «штурмовать, бой на тактической карте»,
monitor_event ButtonPressed ButtonPressed siege_assault_button

либо «продолжение осады» -

monitor_event ButtonPressed ButtonPressed siege_maintain_button

Этот вариант работает только для случая «игрок осаждает ИИ», потому что ИИ при осаде (да и вообще) никаких «кнопок меню» нигде не нажимает. В случае если игрок выбрал продолжение осады, то гарнизонные юниты остаются в поселении и несут потери от осады.

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


Вторым необходимым условием для работы гарнизонного скрипта является наличие специально выделенного «гарнизонного юнита/юнитов». Это нужно для того, чтобы после окончания осады осажденная сторона не получала дополнительное подкрепление в виде гарнизонных отрядов, переживших осаду. И тем более, чтобы гарнизонные отряды не накапливались у фракции в случае, если не было штурма и осада просто снята. Для того, чтобы автоматически распускать «гарнизонные юниты» после осады, требуется отдельная запись для них в файле export_descr_unit.txt. Принципиальным отличием гарнизонного юнита от других является атрибут, который позволит движку игры избирательно применить к нему команду destroy_units. Движок игры позволяет использовать любые придуманные атрибуты. Как правило, используется слово garrison, но вы можете выбрать что угодно для себя (если атрибут из двух и более слов, используется нижнее подчеркивание – garrison_unit, например).

Способов, когда именно удалять гарнизонные юниты, много. Это зависит от вашего видения, как именно должен работать этот скрипт. Для любого варианта прописи возможны оговорки.

В первом и третьем вариантах скрипта команда destroy_units может применяться после штурма и в случае снятия осады. Во втором – после штурма, при снятии осады, а также при отмене штурма и продолжении осады. Если вы хотите получить один набор юнитов, который будет находиться в поселении до конца осады, то никаких «промежуточных» удалений не потребуется. Если вы хотите, чтобы каждый раз при появлении меню штурма состав гарнизона менялся, а также чтобы он не нес потери от пребывания в осажденном поселении, придется распускать его в конце каждого хода.

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

Подробно разберем первый вариант. Лично мне он кажется наиболее логичным.
monitor_event Transgression TransgressionName = TC_INSTIGATE_SIEGE
and FactionIsLocal
and not TargetFactionIsLocal

campaign_wait 0.1

if I_SettlementUnderSiege Paris
and I_EventCounter paris_v_osade = 0 проверка, если игрок напал на ИИ, и счетчик гарнизона нулевой – то есть при данной осаде гарнизон еще не появлялся, спаунится гарнизон
set_event_counter paris_v_osade 1 - все, счетчик сработал, больше ничего не будет спауниться, пока эта осада не завершится
create_unit Paris, Garrison Spearmen, num 3, exp 3, arm 0, wep 0
create_unit Paris, Garrison Cavalry, num 2, exp 3, arm 0, wep 0
create_unit Paris, Garrison Swordsmen, num 1, exp 3, arm 0, wep 0
if RandomPercent > 66
create_unit Paris, Garrison Swordsmen, num 1, exp 3, arm 0, wep 0 – подобным образом вы можете задать случайное появление отряда в гарнизоне
end_if 
end_if
if I_SettlementUnderSiege London - то же самое для другого поселения
and I_EventCounter london_v_osade = 0 - название счетчика для каждого поселения свое, не забываем переименовывать
set_event_counter london_v_osade 1 - мы меняем значение счетчика до спауна армии, чтобы в случае, если в поселении больше нет места для новых отрядов (в этом случае в логе будет ошибка, что невозможно создать отряд в поселении), скрипт не сбился и счетчик не остался нулевым 
create_unit London, Garrison Spearmen, num 1, exp 0, arm 3, wep 0 - обратите внимание, что прописано разное число и параметры юнитов в зависимости от поселения, кому сильнее, кому слабее самостоятельно выбираете
create_unit London, Garrison Cavalry, num 1, exp 0, arm 3, wep 0
create_unit London, Garrison Swordsmen, num 1, exp 0, arm 3, wep 0

end_if
.... - дальше также размножаете для всех нужных поселений

end_monitor


monitor_event FactionTurnEnd FactionType slave
if I_IsFactionAIControlled france
and not I_FactionBesieged france
destroy_units france garrison_unit
end_if
if I_IsFactionAIControlled england
and not I_FactionBesieged england
destroy_units england garrison_unit
end_if
..... и так для всех фракций
if not I_SettlementUnderSiege Paris
set_event_counter paris_v_osade 0
end_if
if not I_SettlementUnderSiege London
set_event_counter london_v_osade 0
end_if
.... и так для всех поселений
end_monitor


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

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

Также при необходимости могу подробно расписать второй и третий варианты прописи скрипта.

Надеюсь, в нынешнем виде информация о написании гарнизонного скрипта стала доступнее. :046:
     DinarMayor
    • Imperial
    Imperial
    Форумчанин

    Date: 06 April 2022, 20:02

    Алексей_Плешков

    IsFortGarrisoned

    Это условие требует экспорта форта, что делают несколько эвентов: захват резиденции, выход гарнизона из форта и несколько других, связанных с миссиями. Но ни один эвент, условие или команда не даст возможность создавать в форте войска, тем более в осаждённом. Есть одна мысль с трансгрессином, но это скорее всего не будет работать. Если даже будет, то сработает до осады и по сути получится почти то де самое, что и в том моем сообщении. вспомнил - это работает при захвате форта.
    Сделать так, чтобы войска появлялись лишь при штурме не получится никак.
       gmingmo
      • Imperial
      Imperial
      Форумчанин

      Date: 26 July 2022, 19:25

      А гарнизонный скрипт работает, когда ИИ нападает на игрока? У игрока появляется гарнизон? Во время игры на меня напали татары, но в моем городе не появился гарнизон. Получается нечестно, что ИИ защищен всегда по факту лучше чем игрок.
         bitterhowl
        • Imperial
        Imperial
        El Compilator

        Date: 26 July 2022, 19:34

        Как настроить, так и будет.

        Предполагается, что игрок защищён межушным ганглием и способен на угрожаемом направлении заблаговременно создать наряд сил и средств.
           Master_TW_DAR
          • Imperial
          Imperial
          Форумчанин

          Date: 29 January 2024, 12:45

          Примеры реализации гарнизонного скрипта. Предалагаю закрепить в данной теме.

          ---

          Сичевые Свитки - Статья - Туториал по созданию гарнизонного скрипта


          Спойлер (раскрыть)


          Сичевые Свитки - Статья - Создание гарнизонного скрипта


          Спойлер (раскрыть)


          Сичевые Свитки - Статья - Пособие по гарнизонному скрипту


          Спойлер (раскрыть)


          ---
             Delabras
            • Imperial
            Imperial
            Форумчанин

            Date: 11 February 2024, 23:08

            bitterhowl (17 December 2021, 05:58):

            monitor_event FactionTurnStart not IsFactionAIControlled
            if I_SettlementUnderSiege Dijon
            set_event_counter no_garrison_dijon 1
            end_if

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


            а не проще добавить в исходный скрипт
            вместо

            Цитата

            and I_EventCounter no_garrison_dijon = 0 - добавили этот счетчик сюда

            условие
            and not SettlementIsLocal
            зачем дополнительные мониторы и счетчики добавлять?


            ЗЫ есть условие по которому можно понять что это человек осаждает город а не ИИ?

            Цитата

            and FactionIsLocal
            and not TargetFactionIsLocal

            или данный код как раз это и решает?
               bitterhowl
              • Imperial
              Imperial
              El Compilator

              Date: 12 February 2024, 00:38

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

              Цитата

              или данный код как раз это и решает?
              да
                 Delabras
                • Imperial
                Imperial
                Форумчанин

                Date: 12 February 2024, 13:00

                Значит не до конца понял зачем эта правка, без нее вроде все норм работает

                Цитата

                monitor_event FactionTurnStart not IsFactionAIControlled
                if I_SettlementUnderSiege Dijon
                set_event_counter no_garrison_dijon 1
                end_if
                end_monitor


                насколько могу судить это монитор начало хода игрока, если город не под осадой то задать эру, которую мы прописываем как усовие спавна гарнизона в городе...

                по сути тоже самое выполняет и:

                Цитата

                monitor_event FactionTurnEnd FactionType slave
                if not I_SettlementUnderSiege Dijon
                set_event_counter dijon_v_osade 0
                end_if
                end_monitor


                Другими словами не совсем понимаю зачем дублирование условия в данном скрипте:

                Цитата

                monitor_event Transgression TransgressionName = TC_INSTIGATE_SIEGE
                and FactionIsLocal
                and not TargetFactionIsLocal

                campaign_wait 0.1

                if I_SettlementUnderSiege Dijon
                and I_EventCounter no_garrison_dijon = 0 - по сути оно вроде как дублирует dijon_v_osade
                and I_EventCounter dijon_v_osade = 0
                set_event_counter dijon_v_osade 1
                create_unit Dijon, NEEE Mortar, num 1, exp 7, arm 0, wep 0
                create_unit Dijon, NEEE Mortar, num 1, exp 7, arm 0, wep 0
                create_unit Dijon, NEEE Mortar, num 1, exp 7, arm 0, wep 0
                create_unit Dijon, Italian MAAR, num 1, exp 4, arm 0, wep 0
                create_unit Dijon, Italian MAAR, num 1, exp 4, arm 0, wep 0
                create_unit Dijon, Italian MAAR, num 1, exp 4, arm 0, wep 0
                create_unit Dijon, Italian MAAR, num 1, exp 4, arm 0, wep 0
                create_unit Dijon, Rebel Pikemene, num 1, exp 4, arm 0, wep 0
                end_if

                end_monitor



                тут получается условие

                Цитата

                and I_EventCounter dijon_v_osade = 0
                set_event_counter dijon_v_osade 1


                исключает повторение сценария до момента снятия осады с поселения, когда счетчик обнуляется...
                   bitterhowl
                  • Imperial
                  Imperial
                  El Compilator

                  Date: 12 February 2024, 13:57

                  Так, стоп)

                  У меня в примере скрипта нет Дижона. У меня Париж и Лондон. Пример скрипта в первом посте темы - самодостаточный, он не нуждается в дополнениях из соседних тем.
                     Delabras
                    • Imperial
                    Imperial
                    Форумчанин

                    Date: 12 February 2024, 17:43

                    bitterhowl (12 February 2024, 13:57):

                    Так, стоп)

                    У меня в примере скрипта нет Дижона. У меня Париж и Лондон. Пример скрипта в первом посте темы - самодостаточный, он не нуждается в дополнениях из соседних тем.

                    вот и я думаю, что вроде излишнее условие, тему пару раз перечитал толком так и не понял в чем ошибка была и зачем доп усовие вводилось :030:
                    так то монитор рабочий, толково добавляется скрипт чутка усложнил пока работает как положено, но нужны дополнительные тесты чтоб отловить возможные баги..
                      • 4 Pages
                      • 1
                      • 2
                      • 3
                      • 4
                       Related Topics
                      МАйболит 66 (Napoleon: Total War)
                      Назовём это заплаткой, или скорее даже лечебным пластырем для игры, склеивющим разорванное целое.
                      Author G Gromozeka
                      Update 19 min. back
                      МNaval Complete Mod (Empire: Total War)
                      Мод добавляет новые корабли из NTW
                      Author G Gromozeka
                      Update Today, 02:23
                      МNaval Complete Mod (Napoleon: Total War)
                      Мод добавляет корабли из ETW
                      Author G Gromozeka
                      Update Today, 02:23
                      Translate a Page
                      Use one of the social networks to log in
                      RegistrationLogin to the forum 
                      «Imperial» · Conditions · Responsibility · About · Cooperation · 21 Feb 2024, 03:38 · Counters