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




bitterhowl

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

Актуальные сведения по написанию гарнизонных скриптов по состоянию на 2021 год
Тема создана: 25 января 2021, 01:42 · Автор: bitterhowl
Просмотров:
 9 494

  • 4 Страниц
  • « Первая
  • 1
  • 2
  • 3
  • 4
 1 
 bitterhowl
  • Imp
Imperial
 

Дата: 25 января 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:
     Алексей_Плешков
    • Imp
    Imperial
     

    Дата: 12 декабря 2021, 21:02

    Прописываю вылазку, вылазка срабатывает, но не правильно. Должно быть 1 отряд копейщика, 1 отряд конницы и 1 отряд мечника, а по факту эти три отряда дублируются несколько раз (копейщик, конница, мечник, копейщик, конница, мечник, копейщик, конница , мечник и так далее). Скрипт в спойлере.
    Спойлер (раскрыть)
       DinarMayor
      • Imp
      Imperial
       

      Дата: 12 декабря 2021, 21:10

      monitor_event GeneralAssaultsResidence CharacterIsLocal
      and InEnemyLands
      and I_SettlementUnderSiege London
      set_counter MayBeVulazka 1
      create_unit London, Garrison Spearmen, num 1, exp 0, arm 0, wep 0
      create_unit London, Garrison Cavalry, num 1, exp 0, arm 0, wep 0
      create_unit London, Garrison Swordsmen, num 1, exp 0, arm 0, wep 0
      set_counter garrison 1
      end_monitor

      А вот так? Не за компом - так бы проверил.
         Алексей_Плешков
        • Imp
        Imperial
         

        Дата: 12 декабря 2021, 21:29

        DinarMayor 12 декабря 2021, 21:10

        monitor_event GeneralAssaultsResidence CharacterIsLocal
        and InEnemyLands
        and I_SettlementUnderSiege London
        set_counter MayBeVulazka 1
        create_unit London, Garrison Spearmen, num 1, exp 0, arm 0, wep 0
        create_unit London, Garrison Cavalry, num 1, exp 0, arm 0, wep 0
        create_unit London, Garrison Swordsmen, num 1, exp 0, arm 0, wep 0
        set_counter garrison 1
        end_monitor

        А вот так? Не за компом - так бы проверил.

        Не работает.
           DinarMayor
          • Imp
          Imperial
           

          Дата: 12 декабря 2021, 21:58

          Вот рабочая вылазка для ИИ
          declare_counter MayBeVulazka
          declare_counter garrison
          
          monitor_event UngarrisonedSettlement not SettlementIsLocal
          and I_SettlementUnderSiege London
          set_counter MayBeVulazka 1
          create_unit London, Garrison Spearmen, num 1, exp 0, arm 0, wep 0
          create_unit London, Garrison Cavalry, num 1, exp 0, arm 0, wep 0
          create_unit London, Garrison Swordsmen, num 1, exp 0, arm 0, wep 0
          set_counter garrison 1
          end_monitor
             bitterhowl
            • Imp
            Imperial
             

            Дата: 13 декабря 2021, 03:07

            Спасибо камраду LEZVIE, он ставил скрипт с вариантом Transgression и нашелся баг, когда гарнизон появлялся в других осажденных городах. Скину исправленный вариант.
               Алексей_Плешков
              • Imp
              Imperial
               

              Дата: 14 декабря 2021, 17:51

              bitterhowl 13 декабря 2021, 03:07

              Спасибо камраду LEZVIE, он ставил скрипт с вариантом Transgression и нашелся баг, когда гарнизон появлялся в других осажденных городах. Скину исправленный вариант.

              Пожалуйста скиньте.
                 bitterhowl
                • Imp
                Imperial
                 

                Дата: 17 декабря 2021, 05:58

                Алексей_Плешков 14 декабря 2021, 17:51

                bitterhowl 13 декабря 2021, 03:07

                Спасибо камраду LEZVIE, он ставил скрипт с вариантом Transgression и нашелся баг, когда гарнизон появлялся в других осажденных городах. Скину исправленный вариант.

                Пожалуйста скиньте.


                Выделю жирным новое.
                В этом примере гарнизон для Дижона

                monitor_event FactionTurnStart not IsFactionAIControlled
                if I_SettlementUnderSiege Dijon
                set_event_counter no_garrison_dijon 1
                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 - добавили этот счетчик сюда
                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

                monitor_event FactionTurnEnd FactionType slave

                set_event_counter no_garrison_dijon 0 - обнуляем все счетчики для всех поселений в конце хода

                if I_IsFactionAIControlled france
                and not I_FactionBesieged france
                destroy_units france garrison_unit
                end_if

                if not I_SettlementUnderSiege Dijon
                set_event_counter dijon_v_osade 0
                end_if

                end_monitor

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

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

                Жирные части размножить для всех нужных поселений, не забывать менять название счетчика под каждое поселение.
                   Алексей_Плешков
                  • Imp
                  Imperial
                   

                  Дата: 11 февраля 2022, 17:40

                  Игрок атакует провинцию, скрипт два города под одним монитором. С этим понятно так как юниты потом исчезают.
                  monitor_event GeneralAssaultsResidence InEnemyLands

                  if I_SettlementUnderSiege Vladimir-Volinskiy
                  create_unit Vladimir-Volinskiy, Garrison Spearmen, num 3, exp 0, arm 1, wep 0
                  end_if

                  if I_SettlementUnderSiege Halych
                  create_unit Halych, Garrison Spearmen, num 3, exp 0, arm 1, wep 0
                  end_if

                  end_monitor

                  Если делать с неисчезающими юнитами по этой схеме и игрок атакует Vladimir-Volinskiy, тогда Sergeant Spearmen появится и в во Владимир-Волынском и в Галиче.

                  monitor_event GeneralAssaultsResidence InEnemyLands

                  if I_SettlementUnderSiege Vladimir-Volinskiy
                  create_unit Sergeant Spearmen, Garrison Spearmen, num 3, exp 0, arm 1, wep 0
                  end_if

                  if I_SettlementUnderSiege Halych
                  create_unit Halych, Sergeant Spearmen, num 3, exp 0, arm 1, wep 0
                  end_if

                  end_monitor
                  Возможно ли прописать неисчезающие юниты под одним монитором, чтоб если атакуешь одну провинцию, чтоб в другой провинции не появлялись юниты.
                     bitterhowl
                    • Imp
                    Imperial
                     

                    Дата: 11 февраля 2022, 17:50

                    Если оба поселения осаждены, то без дополнительных счётчиков точно никак. А дополнительные счётчики это дополнительные мониторы.
                       Алексей_Плешков
                      • Imp
                      Imperial
                       

                      Дата: 11 февраля 2022, 18:33

                      И последний вопрос правильно ли я прописал условия для скриптов, если прописывать неисчезающие юниты?
                      ;-------------------------Игрок напал на ИИ вполе--
                      monitor_event GeneralAssaultsGeneral CharacterIsLocal
                      and IsRegionOneOf London_Province
                      and not RegionIsLocal
                      and not TargetCharacterIsLocal

                      ;-------------------------Деблокация города----------------------------------------
                      monitor_event GeneralAssaultsGeneral not CharacterIsLocal
                      and TargetFactionIsLocal
                      and IsRegionOneOf London_Province
                        • 4 Страниц
                        • « Первая
                        • 1
                        • 2
                        • 3
                        • 4
                         
                        Перевести Страницу
                        Условия · Ответственность · Конфид. · Визитка · 03 июл 2026, 04:41 · Зеркала: ImtwOrg, ImtwSite, ImtwOnline x