+ Ответить в теме
Показано с 1 по 17 из 17

Тема: SDK - технологии

  1. #1
    Доброго времени суток.

    Опять же для начинающих и продолжающих - небольшой опус по работе с SDK. Поехали.

    Цель задачи - добавление новых свойств технологиям (Опять же задача специфическая, но на её примере можно немножко рассмотреть чё такое SDK и с чем его едят).

    Описания установки и сборки SDK приводить не буду, поскольку уже есть хорошая статья на эту тему в меморизе. Так же весьма вскользь задену тему добавления атрибутов в XML и их считывания в SDK - об этом весьма подробно написано в Добавление атрибутов в SDK

    В основном будем рассматривать непосредственно код.
    Итак, в моём примере мне нужно было добавить процентные модификаторы коммерческой отдачи от освоения технологий, а так же открытие возможности построения городов при изучении некоторой технологии.
    Добавляем два параметра в XML-схему (CIV4TechnologiesSchema.xml), один булевского типа:
    bCanFound
    , другой - структура коммерческой отдачи:
    <CommerceModifiers>
    <iCommerce/>
    </CommerceModifiers>

    Добавляем новые параметры всем технологиям, проставляем значения.
    Открываем CvInfos.cpp, пишем в конструкторе класса CvTechInfo::CvTechInfo() :
    инициализацию переменных:
    m_bCanFound(false)
    и
    m_piCommerceModifiers(NULL)
    сразу же добавим в деструктор CvTechInfo::~CvTechInfo()
    корректное удаление массива
    SAFE_DELETE_ARRAY(m_piCommerceModifiers);

    далее пишет функции считывания новых параметров, булевский:
    bool CvTechInfo::isCanFound() const
    {
    return m_bCanFound;
    }
    и, соответственно значение массива по индексу:
    int CvTechInfo::getCommerceModifier(int i) const
    {
    FAssertMsg(i < NUM_COMMERCE_TYPES, "Index out of bounds");
    FAssertMsg(i > -1, "Index out of bounds");
    return m_piCommerceModifiers ? m_piCommerceModifiers[i] : -1;
    }

    и сам массив:
    int* CvTechInfo::getCommerceModifiersArray() const
    {
    return m_piCommerceModifiers;
    }

    Описанные поля класса и функции доступа к ним не забываем добавить в описание класса в CvInfos.h.
    В секции public:
    DllExport bool isCanFound() const; // Exposed to Python
    DllExport int getCommerceModifier(int i) const; // Exposed to Python
    int* getCommerceModifiersArray() const;
    В секции protected:
    bool m_bCanFound;
    int* m_piCommerceModifiers;
    Теперь поправим функцию
    void CvTechInfo::read(FDataStreamBase* stream)
    добавив строки
    stream->Read(&m_bCanFound);
    и
    SAFE_DELETE_ARRAY(m_piCommerceModifiers);
    m_piCommerceModifiers = new int[NUM_COMMERCE_TYPES];
    stream->Read(NUM_COMMERCE_TYPES, m_piCommerceModifiers);
    а так же функцию
    void CvTechInfo::write(FDataStreamBase* stream)
    строками
    stream->Write(m_bCanFound);
    и
    stream->Write(NUM_COMMERCE_TYPES, m_piCommerceModifiers);
    Здесь, думаю, всё понятно. Чтение и запись наших параметров.
    А теперь правим функцию чтения из XML
    bool CvTechInfo::read(CvXMLLoadUtility* pXML)
    добавляя строки
    pXML->GetChildXmlValByName(&m_bCanFound, "bCanFound");
    и
    if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(),"CommerceModifiers"))
    {
    pXML->SetCommerce(&m_piCommerceModifiers);
    gDLL->getXMLIFace()->SetToParent(pXML->GetXML());
    }
    else
    {
    pXML->InitList(&m_piCommerceModifiers, NUM_COMMERCE_TYPES);
    }
    В последнем примере поясню, если вдруг кто не поймёт, выполняемое по ветке else проводит базовую инициализацию массива, если запись этого тэга в XML не найдена.
    Функция SetCommerce взята из стандартных, её стоит использовать, если вы определили внутренние тэги <CommerceModifiers>, хранящие сами изменения отдачи, как <iCommerce>. Иначе придётся писать свою функцию

    На этом с инфосами всё, собираем длл-ку, подкладываем своему моду, запускаемся, тестим. Если всё написано правильно, игра успешно запустится. Новые параметры у нас есть, но пока они ещё ничего не делают. Займёмся теперь описанием функционала.
    Здесь нужно понимать, что есть понятия "Игрок" и есть понятие "Команда". Исследование технологий является процессом, выполняемым командой. Флаг основания городов я добавил команде, а модификаторы коммерческой отдачи каждому игроку (вообще, их можно было добавить и команде, но мне для дальнейшей задумке требовалось приписывать их именно игроку. На текущем примере работать будет так же, как если бы было установлено команде).
    Итак, открываем CvTeam.cpp и пишем в функции CvTeam::reset установку флага по дефолту
    m_bCanFound = false;

    Почему именно в reset? Потому что эта функция вызывается в функции инициализации CvTeam::init и, фактически, является инициализирующей функцией.

    Добавляем функции доступа к новому параметру:
    bool CvTeam::isCanFound() const
    {
    return m_bCanFound;
    }

    void CvTeam::setCanFound(bool bNewValue)
    {
    if (isCanFound() != bNewValue)
    {
    m_bCanFound = bNewValue;
    }
    }

    Прописываем саму переменную m_bCanFound и функции доступа к ней в хидере CvTeam.h (не забываем, что ф-ии доступа нужно ложить в секцию public, чтобы открыть их для питона, если понадобится в дальнейшей в нём)
    Теперь пропишем считывание и установку параметров при исследовании технологии. Находим функцию:
    void CvTeam:rocessTech(TechTypes eTech, int iChange)
    и среди прочих выставляемых параметров добавляем блок возможности освоения городов:
    if (GC.getTechInfo(eTech).isCanFound())
    {
    setCanFound(true);
    }
    А с блоком модификации коммерческой отдачи немножко интереснее. Можно сделать ещё один цикл по типам, но я предпочёл вставить в уже существующий (всё-таки не нужно создавать лишних проходов жрущих лишнее время )
    Находим
    for (iI = 0; iI < NUM_COMMERCE_TYPES; iI++)
    ...
    И выставляем внутри свой блок. Должно быть так:
    for (iI = 0; iI < NUM_COMMERCE_TYPES; iI++)
    {
    if (GC.getTechInfo(eTech).isCommerceFlexible(iI))
    {
    changeCommerceFlexibleCount(((CommerceTypes)iI), iChange);
    }
    for (iJ = 0; iJ < MAX_PLAYERS; iJ++){
    if (GET_PLAYER((PlayerTypes)iJ).getTeam() == getID()){
    GET_PLAYER((PlayerTypes)iJ).changeCommerceRateModifier(((CommerceTypes)iI), (GC.getTechInfo(eTech).getCommerceModifier(iI) * iChange));
    }
    }
    }
    То есть, после установки параметра CommerceFlexible мы модифицируем параметр коммерческого модификатора всех игроков команды.
    Собираем длл, запускаемся, тестируем. Если всё описано верно, должны работать указанные в XML модификаторы коммерческой отдачи при открытии технологий. А вот города всё ещё можно строить, независимо от технологий. Потому что мы только считали значение, но ещё никак его не используем.
    Поехали. Команды юнитов у нас описаны в CvUnit.cpp
    Сперва для удобства записи сделаем функцию в CvPlayer.cpp
    bool CvPlayer::isCanFound() const
    {
    return GET_TEAM(getTeam()).isCanFound();
    }
    И не забываем добавить её в public-секцию описания класса в CvPlayer.h
    Далее открываем CvUnit.cpp и добавляем в функцию bool CvUnit::canFound(const CvPlot* pPlot, bool bTestVisible) const
    ещё одну проверку. Вместо
    if (!(isFound())
    пишем
    if (!(isFound() && (GET_TEAM(getTeam()).isCanFound()))
    это условие будет проверять, есть ли у нашей команды возможность строить города, которая задаётся открытием технологий.
    Теперь ограничим поведение юнитов АИ в файле CvUnitAI.cpp
    В функции
    void CvUnitAI::AI_settleMove()
    меняем условие if (canFound(plot()))
    на if (GET_PLAYER(getOwnerINLINE()).isCanFound() && canFound(plot()))
    Эта проверка производится там в трёх блоках, нужно поправить все три.

    Здесь сделаю небольшое отступление. Сперва я пробовал добавить проверку в саму функцию ::canFound плейера. Но при этом АИ начинает думать, что он не может строится на конкретной проверяемой клетке и начинает оценивать следующую. В результате получается очень сильное подвисание АИ. Добавив проверку в описанном выше месте, мы блокируем поиск АИ места для строительства, если он в принципе ещё не может строится.

    Итак, собираем dll, запускаемся и проверяем. Если у нас нет открытия, позволяющего строить города, мы не сможет этого сделать до того, как не откроем его. Здесь возникнет целый ряд проблем с неожиданной победой и самоуничтожением АИ, но этот вопрос требует более детального рассмотрения. По нему есть обсуждение в теме "Вопросы к мододелам". Простейшее решение, которое мне пока удалось найти - задать сеттлеру стратегию по умолчанию Эксплорер, а добавочную сеттлер. При старте с юнитами, помимо сеттлеров, держава не умирает, но сеттлер всё равно дохнет. Поэтому нужно менять самого сеттлера. Блок кода, отвечающий за его удаление, я пока не нашёл.

    Возвращаемся к нашей теме. Теперь новые параметры работают, но хотелось бы ещё и видеть их описание. Во-первых, в подсказке к самим технологиям, во-вторых, отразить на экране города из чего собственно состоит коммерческая отдача.
    Текстовые подсказки описываются в CvGameTextMgr.cpp.
    Нас будет интересовать функция описания технологии:
    void CvGameTextMgr::setTechHelp(CvWStringBuffer &szBuffer, TechTypes eTech, bool bCivilopediaText, bool bPlayerContext, bool bStrategyText, bool bTreeInfo, TechTypes eFromTech)
    Среди выводы прочих флагов добавляем вызов
    buildCanFoundString(szBuffer, eTech, true, bPlayerContext);
    Сама функция формирования строки выглядит так:
    void CvGameTextMgr::buildCanFoundString(CvWStringBuffer &szBuffer, TechTypes eTech, bool bList, bool bPlayerContext)
    {
    if (GC.getTechInfo(eTech).isCanFound() && (!bPlayerContext || !(GET_TEAM(GC.getGameINLINE().getActiveTeam()).isCanFound())))
    {
    if (bList)
    {
    szBuffer.append(NEWLINE);
    }
    szBuffer.append(gDLL->getText("TXT_KEY_MISC_ENABLES_FOUND"));
    }
    }
    Отображаемый текст нужно положить в описание тэга TXT_KEY_MISC_ENABLES_FOUND в CIV4GameTextInfos.xml
    Не забываем добавить функцию в хидер CvGameTextMgr.h

    Возвращаемся к функции описания технологии и среди прочих блоков описания добавляем
    int aiCommerces[NUM_COMMERCE_TYPES];
    for (iI = 0; iI < NUM_COMMERCE_TYPES; ++iI)
    {
    aiCommerces[iI] = GC.getTechInfo(eTech).getCommerceModifier(iI);
    }
    setCommerceChangeHelp(szBuffer, L", ", L"", L"", aiCommerces, true, false);
    То есть, читаем модификаторы ком.отдачи из описания технологии и формируем стандартной функцией строку с внятным описанием.
    Примечание: если предпоследним параметром в setCommerceChangeHelp передать false, то проценты рисоваться не будут, то есть будет показано количественное приращение. Разумеется, чтобы и логически приращивались не проценты, а абсолютные величины, нужно при освоении технологии вызывать не changeCommerceRateModifier, а changeCommerceRate.

    Теперь добавим описание на экран города. Находим функцию
    void CvGameTextMgr::setCommerceHelp(CvWStringBuffer &szBuffer, CvCity& city, CommerceTypes eCommerceType)
    и добавляем туда в то место, где хотим видеть информацию о модификаторах от технологий (у меня перед мод. от институтов) блок:

    int iTechMod = 0;
    for (int i = 0; i < GC.getNumTechInfos(); i++)
    {
    if (GET_TEAM(owner.getTeam()).isHasTech((TechTypes)i))
    {
    iTechMod += GC.getTechInfo((TechTypes)i).getCommerceModifier(eCommerceType);
    }
    }
    if (0 != iTechMod)
    {
    szBuffer.append(gDLL->getText("TXT_KEY_MISC_HELP_YIELD_TECH", iTechMod, info.getChar()));
    szBuffer.append(NEWLINE);
    iModifier += iTechMod;
    }
    Не забываем положить внятный текст в CIV4GameTextInfos.xml для ключа TXT_KEY_MISC_HELP_YIELD_TECH.

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

    Надеюсь, описанный пример поможет начинающим разработчикам лучше ориентироваться в SDK

    С уважением, Волод.
    продвинь это сообщение в соцсеть:  

  2. #2
    идейный враг всяких трансформероB

    Аватар для Snake_B


    Регистрация
    14.09.2007
    Адрес
    Донецк-Камчатка....
    Сообщений
    13,314
    <div class='quotetop'>Цитата(Волод * 30.1.2010, 3:08) [snapback]323566[/snapback]</div>Ссылки лучше делать так...

    <div class='quotetop'>Цитата(Волод * 30.1.2010, 3:08) [snapback]323566[/snapback]</div>
    {
    return m_bCanFound;
    }
    [/b]
    а код так...
    [code]
    {
    продвинь это сообщение в соцсеть:  

  3. #3
    А название файлов и тому подобное, лучше выделять жирным шрифтом.

    Открываем CvInfos.cpp, пишем в конструкторе класса CvTechInfo::CvTechInfo() :
    инициализацию переменных:

    А вообще спасибо огромное за статью, эх побольше бы таких было бы. Модостроение бы тогда намного дальше продвинулось.
    продвинь это сообщение в соцсеть:  
    Я иду меж стен и дворцовых башен,
    Мимо перекрестков веков и лиц,
    Мимо городов, площадей и пашен,
    Познавая мир на холсте страниц.

  4. #4
    идейный враг всяких трансформероB

    Аватар для Snake_B


    Регистрация
    14.09.2007
    Адрес
    Донецк-Камчатка....
    Сообщений
    13,314
    <div class='quotetop'>Цитата(Хальк Юсдаль * 30.1.2010, 4:13) [snapback]323570[/snapback]</div>
    А вообще спасибо огромное за статью, эх побольше бы таких было бы. Модостроение бы тогда намного дальше продвинулось.
    [/b]
    не дальше, а шире... :-p
    продвинь это сообщение в соцсеть:  

  5. #5
    Очень интересная статья. Большое спасибо.

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

    Заранее большое спасибо.
    продвинь это сообщение в соцсеть:  

  6. #6
    Модифицированные файлы прилагаю.
    Но кроме описанных в статье изменений там есть и другие Например, добавлена процентная коммерческая отдача от проектов, которая ещё не описывается в текстах подсказок, а так же добавлена миссия "Разбить стоянку" для сеттлеров, которая пока увеличивает базовый научный рост на 10% при старте и уменьшает его на 10% при прекращении, а анимируется, как укрепление.

    В целом для настоящей игры использовать эти исходники ещё нельзя, поскольку АИ ещё не использует нововведённую миссию и, следовательно, с первых ходов начнёт жёстко проигрывать. Но для ознакомления сойдёт.

    Поскольку размер загружаемых файлов ограничен, выложу в архиве.

    С уважением, Волод.
    Вложения Вложения
    продвинь это сообщение в соцсеть:  

  7. #7
    Вставлю я и свои 5 копеек.
    Хочу заметить что это только теория, на практике не проверенная !!!
    Волод упустил одну маленькую деталь: новые фишки не будут показыватся на дереве технологий. Я покажу как это исправить.
    Открываем файл Assets\Python\Screens\CvTechChooser.py и находим
    def placeTechs (self).
    Внутри этой функции ищем цикл
    for i in range(gc.getNumTechInfos()):
    В нем после строчек
    fX = X_START
    пишем[code]if gc.getTechInfo(i).isCanFound():
    продвинь это сообщение в соцсеть:  
    Если новые технологии позволяют обходится без услуг простых людей - это прогресс, а если новые технологии позволяют обходится без услуг миллионеров и крупных компаний - это нарушение авторских прав.
    Мой мод

  8. #8
    Заморочиться, наверное, стоит, но потом, когда времени больше будет.
    А сейчас работает всё и так ) На дереве технологий прекрасно всё рисуется.

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

    С уважением, Волод.
    продвинь это сообщение в соцсеть:  

  9. #9
    <div class='quotetop'>Цитата(Волод * 31.1.2010, 18:24) [snapback]323705[/snapback]</div>
    Там просто многие функции сперва вызывают питоновский вариант, и если питон сделает свою работу и вернёт им нужный флаг, начинают делать свой. Я не стал заморачиваться с питоном, а напрямую внёс изменения в сдк.[/b]
    А где именно?
    продвинь это сообщение в соцсеть:  
    Если новые технологии позволяют обходится без услуг простых людей - это прогресс, а если новые технологии позволяют обходится без услуг миллионеров и крупных компаний - это нарушение авторских прав.
    Мой мод

  10. #10
    Класс CvGameTextMgr, функция setCommerceChangeHelp для показа на городском экране и setTechHelp для показа во всех окнах технологий.

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

  11. #11
    <div class='quotetop'>Цитата(Волод * 31.1.2010, 19:12) [snapback]323711[/snapback]</div>
    Класс CvGameTextMgr, функция setCommerceChangeHelp для показа на городском экране и setTechHelp для показа во всех окнах технологий.

    Как в первом посте описывал - добавил строчку, в которую выводится текст о том, что технология позволяет основывать города. И добавил стандартный блок с показателями коммерческих изменений к выходной строке.[/b]
    Так это, вроде, только подсказка, когда курсор на теху наводишь.
    А я про показ кнопок на панельке технологии.
    продвинь это сообщение в соцсеть:  
    Если новые технологии позволяют обходится без услуг простых людей - это прогресс, а если новые технологии позволяют обходится без услуг миллионеров и крупных компаний - это нарушение авторских прав.
    Мой мод

  12. #12
    <div class='quotetop'>Цитата(NeseryozniyVET * 31.1.2010, 20:19) [snapback]323712[/snapback]</div>
    Так это, вроде, только подсказка, когда курсор на теху наводишь.
    А я про показ кнопок на панельке технологии.
    [/b]
    Кнопки коммерческой отдачи показываются на панели технологии. Я же стандартный элемент взял, который в других местах рисуется, и добавил его к панели технологий вместе с текстом и кнопками. А вот на счёт нового параметра (который возможность освоения городов) - это да, отображается только текст, без кнопки.
    продвинь это сообщение в соцсеть:  

  13. #13
    Король Аватар для Blacksun


    Регистрация
    10.05.2006
    Адрес
    М.О. г. Раменское
    Сообщений
    1,873
    А можно поподробнее, чего мы ищем ? (Ведь АИ и так умеет строить города.). И еще. Функции для АИ и для челов, совершенно разные. Поэтому надо вставлять коды и для АИ.
    продвинь это сообщение в соцсеть:  
    Программирование - это не то, что ты думаешь.... - Это то, что думает о тебе компьютер.
    http://blacksun.civfanatics.ru
    -------------------------------------------------
    MTDG2 - [civ]christianity[/civ]Монархия
    ---------------------------------
    Председатель CFR Awards 2007
    ---------------------------------
    Председатель CFR Awards 2008

  14. #14
    <div class='quotetop'>Цитата(Blacksun * 4.2.2010, 12:10) [snapback]323983[/snapback]</div>
    И еще. Функции для АИ и для челов, совершенно разные. Поэтому надо вставлять коды и для АИ.[/b]
    Тоесть, в данном примре если человек выучит теху то получит бонус, а если ИИ выучти то толку не будет ?
    продвинь это сообщение в соцсеть:  
    Если новые технологии позволяют обходится без услуг простых людей - это прогресс, а если новые технологии позволяют обходится без услуг миллионеров и крупных компаний - это нарушение авторских прав.
    Мой мод

  15. #15
    Король Аватар для Blacksun


    Регистрация
    10.05.2006
    Адрес
    М.О. г. Раменское
    Сообщений
    1,873
    <div class='quotetop'>Цитата(NeseryozniyVET * 4.2.2010, 16:51) [snapback]324020[/snapback]</div>
    <div class='quotetop'>Цитата(Blacksun * 4.2.2010, 12:10) [snapback]323983[/snapback]
    И еще. Функции для АИ и для челов, совершенно разные. Поэтому надо вставлять коды и для АИ.[/b]
    Тоесть, в данном примре если человек выучит теху то получит бонус, а если ИИ выучти то толку не будет ?
    [/b][/quote]

    Дело не в этом. Чел будет стремиться ее учить, потому что получит бонус. А АИ, не будет знать бонуса и поэтому эту теху может учить не в первую очередь.
    продвинь это сообщение в соцсеть:  
    Программирование - это не то, что ты думаешь.... - Это то, что думает о тебе компьютер.
    http://blacksun.civfanatics.ru
    -------------------------------------------------
    MTDG2 - [civ]christianity[/civ]Монархия
    ---------------------------------
    Председатель CFR Awards 2007
    ---------------------------------
    Председатель CFR Awards 2008

  16. #16
    <div class='quotetop'>Цитата</div>
    Дело не в этом. Чел будет стремиться ее учить, потому что получит бонус. А АИ, не будет знать бонуса и поэтому эту теху может учить не в первую очередь.
    [/b]
    АИ будет изучать технологии согласно заданной в её описании схеме. В том числе, опираясь на "ароматы" и числовые значения ценности для АИ.

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

    С уважением, Волод.
    продвинь это сообщение в соцсеть:  

  17. #17
    Король Аватар для Blacksun


    Регистрация
    10.05.2006
    Адрес
    М.О. г. Раменское
    Сообщений
    1,873


    Может для данного случая это не так актуально, но, когда мне надо было делать так, чтобы АИ делал тераформинг, приходилось исправлять код для АИ рабочего. (Это так, на будущее)
    продвинь это сообщение в соцсеть:  
    Программирование - это не то, что ты думаешь.... - Это то, что думает о тебе компьютер.
    http://blacksun.civfanatics.ru
    -------------------------------------------------
    MTDG2 - [civ]christianity[/civ]Монархия
    ---------------------------------
    Председатель CFR Awards 2007
    ---------------------------------
    Председатель CFR Awards 2008

+ Ответить в теме

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
Рейтинг@Mail.ru

free counters