500
  • Страница 1 из 1
  • 1
Модератор форума: tupi857  
Форум » Видоизменение » Технологии » Руководство по написанию скриптов ( часть 2)
Руководство по написанию скриптов ( часть 2)
# 108:06 12/06/2019
9
tupi857 (jango)
Cмотритель

 Вне сети
Идентификационные номера
Идентификаторы - это постоянные целые числа, сгенерированные игрой для идентификации определенных элементов игры, таких как одна конкретная единица на карте, одна конкретная технология в техническом дереве, ресурс и т. д. Если вы хотите манипулировать этим элементом, вы должны знать его идентификатор. Например, если вы хотите исследовать определенную технологию, вы должны выбрать ее идентификатор и начать план исследования (о планах мы поговорим позже).
Идентификатор элемента зависит от порядка, в котором этот элемент создан / определен. Первый идентификатор равен 0, второй - 1, третий - 2 и т. Д.
Не волнуйтесь, есть способы определения идентификаторов:

Константы
При запуске, когда вы запускаете исполняемый файл, AoE3 определяет константу для каждой технологии, protounit, цивилизации и т. Д. Чтобы узнать, что идентифицирует константа, есть префикс:
Tech ID : cTech
Protounit / ID типа устройства: cUnitType
Цивилизация: cCiv
Культура: cCulture
Тактика: cTactic
Ресурс:

Запросы cResource
Единицы, находящиеся на карте, не идентифицируются константами - это было бы просто безумием. Чтобы их найти, мы используем запросы. Мы поговорим о запросах позже.
Просто будьте осторожны: идентификатор устройства НЕ совпадает с идентификатором типа Protounit / Unit. Представьте, что на карте 50 мушкетеров. Каждый из них имеет свой собственный уникальный идентификатор (в зависимости от порядка, в котором они появляются на карте), но все они имеют один и тот же идентификатор protounit (в Protoy). Если вы хотите, чтобы ИИ удалил один из них, вы должны сначала определить его ID, а затем удалить его.

Теперь открой техтрей. Вы увидите код XML. Одна технология определяется следующим образом:

Код
<Tech name ='NameOfTheTech' type ='Normal'>
    Here are a bunch of other XML codes.
    But we don't need them.
    ...
    ...
</Tech>


Первая технология, определенная в techtreey, это Age0French , поэтому ее идентификатор равен 0. Вторая технология определена как NativeAztec , поэтому ее идентификатор равен 1. И вы можете изучить techtree, если хотите. Но вы, вероятно, нет: с.
Ну, раньше мы говорили о константах и ​​префиксах. Эта константа содержит идентификатор первой технологии: cTechAge0French . Это чувствительно к регистру! Затем cTechNativeAztech содержит идентификатор технологии NativeAztec и т. Д.

То же самое относится к прототипам, цивилизациям, тактике и т. Д. Например, идентификатор protounit мушкетера содержится в константе cUnitTypeMusketeer .

В справочнике есть несколько других констант (см. Первую часть), поэтому не стесняйтесь смотреть ;)

Создание и манипулирование «объектом»

Извините, я не нашел / не знаю подходящего слова, поэтому я использовал «объект» ...

Обычно, каждый раз, когда вы хотите что-то сделать, например, найти одну единицу или начать исследование (например), вы должны сначала создать для него соответствующий «объект». Этому объекту в игре будет присвоен целочисленный идентификатор, и вы должны будете сохранить этот идентификатор в переменной, чтобы вы могли найти объект, не зная действительного числа. Обычно это работает так:

Код
int objectID = creatorFunction();
manipulatingFunction(objectID, settings);

Вот пример для создания запроса

Код
int queryEnemyTC = kbUnitQueryCreate("Find enemy Town center");
kbUnitQuerySetUnitType(queryEnemyTC, cUnitTypeTownCenter);
kbUnitQuerySetPlayerRelation(queryEnemyTC, cPlayerRelationEnemyNotGaia);
kbUnitQuerySetState(queryEnemyTC, cUnitStateAlive);
kbUnitQueryResetResults(queryEnemyTC);
int numTC = kbUnitQueryExecute(queryEnemyTC);
if (numTC >= 1)
{
    int enemytcID = kbUnitQueryGetResult(queryEnemyTC, 0);
}


Что просходит?
1. Создается запрос под названием «Найти вражеский центр города». Идентификатор для этого генерируется.
2. Этот идентификатор хранится в переменной queryEnemyTC.
3. Для запроса мы указываем несколько критериев: единица для поиска - это центр города, он принадлежит врагу и является живым (не свернутым и не строящимся).
4. Результаты предыдущего исследования (если есть) очищаются.
5. Запрос выполняется. Список всех TC, найденных по запросу, генерируется, и общее количество найденных TC сохраняется в переменной numTC .
6. Если запрос обнаружил TC ( if (numTC> = 1) ), сохраните идентификатор первого TC в списке в переменной врага tcID .

Хорошие примеры запросов можно найти в AI Vanilla (папка AoE3 \ AI3 \ aiMain.xs), например, getUnit, getUnitByLocation, ...

Планы
Планы - это наборы функций и констант, которые назначают единицы для определенных задач. Есть несколько типов планов. Например, «план исследования» заставляет юниты исследовать карту. Составление плана обычно происходит следующим образом:
1. Вы создаете план, присваиваете ему имя и тип и сохраняете его идентификатор в переменной.
2. Вы применяете несколько настроек для того, что он будет делать, его приоритет и т. Д.
3. Вы активируете его, чтобы он запускал задачи.

Вот пример, который заставляет исследователя исследовать карту:

Код
int explorePlan = aiPlanCreate("ExplorerExplore", cPlanExplore);
aiPlanSetDesiredPriority(explorePlan, 90);
aiPlanAddUnitType(explorePlan, cUnitTypeHero, 1, 1, 1);
aiPlanSetActive(explorePlan, true);


Приоритет
Поскольку планы являются целевыми единицами, несколько планов разных типов могут использовать один и тот же юнит. Устанавливая приоритет, вы решаете, какой план должен использовать этот блок первым, а какие планы - после первого плана и т. Д. Приоритеты обычно начинаются с 0 до 99 (и даже 100). Планы более высоких приоритетов могут «украсть» подразделения из планов более низких приоритетов.
AddUnitType
Эта функция указывает плану использовать cUnitTypeHero, чтобы план не заставлял жителей деревень разведывать. Три «1» - это соответственно «потребность», «желание» и «максимальное» количество разведчиков. Если хотите, вы можете заставить все юниты разведать карту.
Активация
После применения предыдущих «настроек» план активируется. Исследователь должен начать разведку сейчас.

Вот еще один пример, который обучает поселенцев из центра города

Код
int maintainPlan = aiPlanCreate("ExplorerExplore", cPlanTrain);
aiPlanSetVariableInt(planID, cTrainPlanUnitType, 0, cUnitTypeSettler);
aiPlanSetVariableInt(planID, cTrainPlanNumberToMaintain, 0, 10);
aiPlanSetActive(maintainPlan, true);


Переменные
Установка переменных в плане устанавливает / изменяет некоторые вещи, которые должен делать план. Здесь мы рассказываем план по обучению поселенцев, и мы также говорим, чтобы «поддерживать» 10 поселенцев. План будет пытаться продолжать обучение поселенцев, пока не будет 10 поселенцев. Если один из этих поселенцев умирает, план тренируется. Короче говоря, план «поддерживает» 10 поселенцев.

Вы можете увидеть много планов в aiMain (папка AoE3 \ AI3 \).

Что ж, теперь вы можете «обновить» ИИ, который мы создали в первой части:

Код
void main(void)
{
    int explore = aiPlanCreate("Scout", cPlanExplore);
    aiPlanSetDesiredPriority(explore, 90);
    aiPlanSetVariableFloat(explore, cExplorePlanLOSMultiplier, 0, 4.0);
    aiPlanAddUnitType(explore, cUnitTypeHero, 1, 1, 1);
    aiPlanSetActive(explore, true);
}


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

гарнизировать всех поселенцев в центре города:

Код
// Define a query to find units
int queryID = -1; // Remember, IDs always start at zero, so "-1" means "undefined (yet)"

int find(int unit=-1, index=0)
{
    if (queryID < 0) // "undefined" yet
    {
  queryID = kbUnitQueryCreate("FindUnit");
  kbUnitQuerySetPlayerRelation(queryID, cPlayerRelationSelf);
  kbUnitQuerySetState(queryID, cUnitStateAlive);
    }
    if (index==0)
    {
  kbUnitQueryResetResults(queryID);
  kbUnitQuerySetUnitType(queryID, cUnitTypeTownCenter);
  kbUnitQueryExecute(queryID);
    }
    return(kbUnitQueryGetResult(queryID, index));
}

void main(void)
{
    for(i=0;<kbUnitCount(cMyID, cUnitTypeSettler, cUnitStateAlive))
    {
  int unitID = find(cUnitTypeSettler, i);
  aiTaskUnitWork(unitID, find(cUnitTypeTownCenter, 0));
    }
}
LOVEAOE
Форум » Видоизменение » Технологии » Руководство по написанию скриптов ( часть 2)
  • Страница 1 из 1
  • 1
Поиск:
Пятёрка форумщиков