+ Ответить в теме
Страница 2 из 4 ПерваяПервая 123 ... ПоследняяПоследняя
Показано с 21 по 40 из 70

Тема: Уроки SDK. Поэтапно с начала.

  1. #21
    Спасибо, добавил в первый пост. Питоном займусь в ближайшее, относительно время. Так что пригодится весьма и весьма. Заодно хотел спросить.

    В SDK новый параметр будет вызыватся функцией GC.getDefineINT("NEW_PARAMETR"). Это очень медленная функция, поэтому если хотите чтоб с новым параметром расчеты происходили быстро, то надо сделать соответствующие изменения в файлах CvGlobals.cpp и CvGlobals.h на примере существующего параметра MOVE_DENOMINATOR. И уже заместь GC.getDefineINT("NEW_PARAMETR") использовать GC.getNEW_PARAMETR().
    А как удалось выяснить, что она очень медленная? Через установку таймера на выполнение функции? Я вчера CvPlot просматривал, так она там много где используется, например в расчете видимости тайлов. Если заменить её на GC.getNEW_PARAMETR() то это должно по идее ускорить игру, хоть и не намного.

    Вообще, какие основные тормоза в SDK? Я знаю некоторые.
    Callback'и в Питон, их и так большей частью ещё в RevDCM заблокировали, а я оставшиеся заблокировал, теперь даже расчет опыта юнита до следующего уровня у меня идет через SDK.
    Pathfinding - в Caveman2Cosmos они свой сделали, с поддержкой многопоточности и без использования exe-файла, как я понял. Надо будет сделать по аналогии, но мне до это уровня ещё расти и учить.
    Циклы через весь массив, для обнаружения нужной связи. Например через весь набор прокачек, имеется ли такая у юнита. Как бы ещё научить сохранять связи между ними, и автоматически пересчитывать при изменении XML. Эту проблему устранили в Realism Invictus.

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

  2. #22
    1) Потому что GC.getNEW_PARAMETR() возвращает число, хранящееся в переменной. А GC.getDefineINT("NEW_PARAMETR") сначала ищет по названию нужную переменную, а только потом возвращает число.
    Когда я начинал осваивать SDK, то сделал чтоб юниты по диагоналям передвигались не так далеко как по вертикалям и горизонталям, и сделал я это через GC.getDefineINT("NEW_PARAMETR"). Игроки, которые играли в мой мод, сразу стали жаловатся что ИИ стал дольше думать. Когда я сделал все через GC.getNEW_PARAMETR(), жалобы исчезли.

    2) Расчет лучшего тайла для города делается в конце каждого хода игроков. Я сделал так чтоб этот алгоритм выполнялся перед ходом поселенца. ИИ запоминает что выбрал лучший тайл, и если не произошли события, которые могут повлиять на выбор, то алгоритм не выполняется.
    Возмжность апгредить юнита в другого проверяется через рекурсивную функцию для каждого юнита каждый ход. Я этот алгоритм вызываю при запуске мода для каждого юнита и сохраняю результат в единственный битовый масив. Этат алгоритм настолько медленный, что мой мод стал долго запускаться. Поэтому я этот алгоритм сделал многопоточным. При запуске моего мода можно посмотреть загрузку процессора, если загрузились все ядра - значит выполняется этот алгоритм.
    Многие расчеты я тоже делаю при запуске мода или игры, и уже в самой игре использую заместь алгоритмов заранее вычесленый результат.
    Есть еще метод замены ветвлений (if else) на математические выражения (современные процессоры не любят ветвления).
    Например
    if (x > 0) {y += x;}
    заменяется на
    y += x * (x > 0);.
    Правда, код после этого делается плохо читаемым, поэтому оптимизацию ветвлений я всегда сопровождаю коментариями оригинального кода
    y += x * (x > 0);//if (x > 0) {y += x;}.

    А в каком файле (и название функции) находится альтернатива Pathfinding в моде Caveman2Cosmos? Хочу себе такое зделать.
    продвинь это сообщение в соцсеть:  
    Последний раз редактировалось NeseryozniyVET; 31.08.2013 в 20:31.
    Если новые технологии позволяют обходится без услуг простых людей - это прогресс, а если новые технологии позволяют обходится без услуг миллионеров и крупных компаний - это нарушение авторских прав.
    Мой мод

  3. #23
    Спасибо, заменю ради интереса GC.getDefineINT("PLOT_VISIBILITY_RANGE") на GC.getPLOT_VISIBILITY_RANGE().


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

    Возмжность апгредить юнита в другого проверяется через рекурсивную функцию для каждого юнита каждый ход.
    А это кажется в RevDCM побеждено, туда ведь был включен Sanguo Mod Performance в котором с этой проблемой боролись.

    Есть еще метод замены ветвлений (if else) на математические выражения (современные процессоры не любят ветвления).
    Про такое даже не слышал, запомню на будущее, ещё пригодится.

    А в каком файле (и название функции) находится альтернатива Pathfinding в моде Caveman2Cosmos? Хочу себе такое зделать.
    CvPathGenerator.cpp и CvPathGenerator.h если правильно помню.
    продвинь это сообщение в соцсеть:  

  4. #24
    Ах, да, оставлю ссылку здесь, чтобы не забылась. Как раз в тему. А пока попробую разобраться, что такое профайлер и как им пользоваться на примере Civ4.

    http://forums.civfanatics.com/showthread.php?t=487573
    продвинь это сообщение в соцсеть:  

  5. #25
    Буду писать новыми постами, все равно уроки по ссылкам в первом посте рассредоточены, а под новые есть зарезервированное место.

    Побаловался с этими профайлерами, с Very Sleepy, LTProf и вот сейчас CodeAnalysist.

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






    Вот скрин из

    Very Sleepy

    Что смущает, из того что мне понятно. Функция initCvPythonExtensions она жрет просто какое-то дико неприличное количество ресурсов, это как я понимаю использование игрой питона?

    Далее уже по доступному CvGameCoreDLL.dll. Неожиданный результат по функциям.
    shuffle - ещё понятно, хотя надо посмотреть, что она именно делает.
    CvCity::getTeam - уже странно, но все таки.
    getUnit - ладно, это самое понятное.
    CvPlayerAI::AI_maxGoldPerTurnTrade - а вот это как? Как он умудряется так золото свое считать.
    CvPlayerRecord::getMinutesPlayed - понятно, но что-то больно много этот подсчет минут себе требует.
    CvPlayer::getAdvancedStartVisibilityCost - а это-то ему зачем. Игру начинал нормальную, безо всяких там AdvancedStart.

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

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

    Немного изменил её, дабы calculateGoldRate() высчитывался лишь один раз.

    Скрытый текст
    Код:
    int CvPlayerAI::AI_maxGoldPerTurnTrade(PlayerTypes ePlayer) const
    {
    	int iMaxGoldPerTurn;
    	int GoldRate = calculateGoldRate();//Cansei 1.09.2013
    
    	FAssert(ePlayer != getID());
    
    	if (isHuman() || (GET_PLAYER(ePlayer).getTeam() == getTeam()))
    	{
    //		iMaxGoldPerTurn = (calculateGoldRate() + (getGold() / GC.getDefineINT("PEACE_TREATY_LENGTH")));//Cansei 1.09.2013
    	iMaxGoldPerTurn = (GoldRate + (getGold() / 10));
    	}
    	else
    	{
    		iMaxGoldPerTurn = getTotalPopulation();
    
    		iMaxGoldPerTurn *= GC.getLeaderHeadInfo(getPersonalityType()).getMaxGoldPerTurnTradePercent();
    		iMaxGoldPerTurn /= 100;
    
    		iMaxGoldPerTurn += std::min(0, getGoldPerTurnByPlayer(ePlayer));
    	}
    
    //	return std::max(0, std::min(iMaxGoldPerTurn, calculateGoldRate()));//Cansei 1.09.2013
    	return std::max(0, std::min(iMaxGoldPerTurn, GoldRate));
    }


    Функция немного присмирела, но все равно остается неприлично прожорливой. Буду смотреть дальше, вглубь calculateGoldRate().
    Код:
    0x2eb90a0 	CvPlayerAI::AI_maxGoldPerTurnTrade 	2.25
    Код:
    0x2eb90a0        CvPlayerAI::AI_maxGoldPerTurnTrade 	2.80
    Код:
    0x2eb90a0        CvPlayerAI::AI_maxGoldPerTurnTrade 	1.96
    продвинь это сообщение в соцсеть:  

  7. #27
    Попробуй заменить условные переходы на математические выражения вот так.

    замени
    iMaxGoldPerTurn += std::min(0, getGoldPerTurnByPlayer(ePlayer));
    на
    int iGoldPerTurnByPlayer = getGoldPerTurnByPlayer(ePlayer);
    iMaxGoldPerTurn += iGoldPerTurnByPlayer * (iGoldPerTurnByPlayer < 0);
    //iMaxGoldPerTurn += std::min(0, getGoldPerTurnByPlayer(ePlayer));

    замени
    return std::max(0, std::min(iMaxGoldPerTurn, GoldRate));
    на
    int iDelta = iMaxGoldPerTurn - GoldRate;
    int iReturn = iMaxGoldPerTurn - iDelta * (iDelta > 0);
    //iReturn = std::min(iMaxGoldPerTurn, GoldRate)
    iReturn *= (iReturn > 0);//iReturn = std::max(0, iReturn);
    return iReturn;

    Мне самому интересно насколько такая замена эффективней.


    А эти програмки анализируют время затраченое на каждую функцию ?


    У себя в моде я оптимизировал CvCity::getTeam(). Она по твоим скриншотам 4,73% жрет
    Код:
    TeamTypes CvCity::getTeam() const
    {
    //VET Optimization - begin /
    	//return GET_PLAYER(getOwnerINLINE()).getTeam();
    	return m_eTeam;
    //VET Optimization - end /
    }
    Может ее еще и инлайновой сделать ?
    продвинь это сообщение в соцсеть:  
    Последний раз редактировалось NeseryozniyVET; 01.09.2013 в 17:08.
    Если новые технологии позволяют обходится без услуг простых людей - это прогресс, а если новые технологии позволяют обходится без услуг миллионеров и крупных компаний - это нарушение авторских прав.
    Мой мод

  8. #28
    Цитата Сообщение от NeseryozniyVET Посмотреть сообщение
    Попробуй заменить условные переходы на математические выражения вот так.
    Мне самому интересно насколько такая замена эффективней.
    Заменю на будущее, но пока эффекта от такой замены не ожидается, потому что все куда хитрее.

    По направлению calculateGoldRate() нашел мало чего интересного, разве что громоздкую формулу расчета инфляции, да callback в питон на запрос ExtraUnitCosts(или как их там), функцию оставил, а коллбек прибил, ибо нефиг. Заменил его на считывание переменной напрямую из SDK. Потом я вообще заменил calculateGoldRate() на getGold()/10/ Ну чтобы выдавал количество золота в казне/10 ходов. Да вот только пользы мало было.

    Начал смотреть, обнаружил что вызывается AI_maxGoldPerTurnTrade преимущественно из питона. И стоит там привидение из класса CvPlayer к CvPlayerAI через dynamic_cast. А вот это походу жрет куда больше, чем вычисления расходов. Заодно как один из источников вызовов обнаружил Civ4Alert это из RevDCM, когда включен, каждый ход сообщает об изменения в торговле AI. Вырубил, но толку все равно мало.

    Код:
     int CyPlayer::AI_maxGoldPerTurnTrade(int iPlayer)
    {
    	CvPlayerAI* pPlayer = dynamic_cast<CvPlayerAI*>(m_pPlayer);
    	if (pPlayer)
    	{
    		return (pPlayer->AI_maxGoldPerTurnTrade((PlayerTypes)iPlayer));
    	}
    	return 0;
    }
    Думаю проще будет перенести эту функцию в CvPlayer. Ну это потом. Программки эти как раз и анализируют использование процессора. Причем на саму CvGameCoreDLL приходится в лучшем случае 16-17% загрузки двухядерника. Обычно меньше. Проверяю на автоплее, ставлю его на 50-100 ходов, на поздних стадиях на 20. И сворачиваю игру, как правило. Ресурсов больше идет на exe-файл, причем в том около 70% из него идет на питон. Если игру держать свернутой подольше, то тут уже CvGameCoreDLL вырывается вперед.

    Пытался понять в чем дело, думал, Потом обнаружил, что Very Sleepy ещё может и анализировать стеки вызовов. Причем как вызывающие выбранную функцию, так и вызываемые ею.


    Похоже что большая часть вызовов из AI_get_Greeting, немного поменьше из shuffle. Основная проблема стало быть в AI_get_Greeting.

    С вызовами из AI_maxGoldPerTurnTrade ещё веселее. Как она умудряется так их вызывать, понятия не имею.



    Буду думать, скорее всего перекомпилирую в debug и буду смотреть по точкам останова. Заодно ещё обнаружил, что CvTeam::getCompletedSpaceshipProjects жрет от 1% до 1.5%. И это притом, что игра у меня только один раз до Ренессанса добиралась.
    продвинь это сообщение в соцсеть:  

  9. #29
    Цитата Сообщение от NeseryozniyVET Посмотреть сообщение
    Попробуй заменить условные переходы на математические выражения вот так.

    У себя в моде я оптимизировал CvCity::getTeam(). Она по твоим скриншотам 4,73% жрет

    Может ее еще и инлайновой сделать ?
    Надо будет сделать на будущее, но она хоть очевидная. А вот большая часть функций из этого топа, как-то нет. Прогонял игру без модов, прощелкивая ходы. Соотношение функций там получилось другое.
    CvPlayer::getAdvancedStartVisibilityCost я там даже не заметил. Но с ней буду разбираться отдельно. Тут либо в RevDCM косяк, в стиле ихних пиратских судов нещадно тормозивших, потому что какой-то умник решил бороться с варварскими судами застрявшими в ледяных озерах, через генерацию патчфайндинга на каждый тайл в двухкратном радиусе их хода. А я то думал, почему у меня варварские суда так дико тормозят. Либо же мой, я ввел забывание тайлов, может и оно имеет отношение. Пока подробно не смотрел. Но вот AI_maxGoldPerTurnTrade и там была в верхней десятке. AI_get_Greeting так вообще на втором месте.
    продвинь это сообщение в соцсеть:  

  10. #30
    Отошел покопаться в другом направлении, а именно CvRandom::get Внешне непримечательная, но как показывает Very Sleepy, на её внутренние вызовы приходится 25% всей работы. Причем она обращается к .exe файлу, а тот в свою очередь вызывает кучу внешних в том числе и те, что наиболее ресурсоемкие. Вызывается она чаще всего через питон.





    Отвечает она, судя по названию за рандом. Выглядит вот так.

    Скрытый текст
    Код:
    unsigned short CvRandom::get(unsigned short usNum, const TCHAR* pszLog)
    {
    	if (pszLog != NULL)
    	{
    		if (GC.getLogging() && GC.getRandLogging())
    		{
    			if (GC.getGameINLINE().getTurnSlice() > 0)
    			{
    				TCHAR szOut[1024];
    				sprintf(szOut, "Rand = %d on %d (%s)\n", getSeed(), GC.getGameINLINE().getTurnSlice(), pszLog);
    				gDLL->messageControlLog(szOut);
    			}
    		}
    	}
    
    	m_ulRandomSeed = ((RANDOM_A * m_ulRandomSeed) + RANDOM_C);
    
    	unsigned short us = ((unsigned short)((((m_ulRandomSeed >> RANDOM_SHIFT) & MAX_UNSIGNED_SHORT) * ((unsigned long)usNum)) / (MAX_UNSIGNED_SHORT + 1)));
    
    	return us;
    }

    В питон передается, если я правильно понимаю, через функцию в файле CyRandomInterface.cpp
    Содержимое файла выглядит так.

    Скрытый текст
    Код:
    #include "CvGameCoreDLL.h"
    #include "CvRandom.h"
    # include <boost/python/overloads.hpp>
    using namespace boost::python;
    
    BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(CvRandom_get_overloads, CvRandom::get, 2, 2)
    
    //
    // published python interface for CvRandom
    //
    void CyRandomPythonInterface()
    {
    	OutputDebugString("Python Extension Module - CyRandomPythonInterface\n");
    
    	python::class_<CvRandom>("CyRandom")
    		.def("get", &CvRandom::get, CvRandom_get_overloads( args("usNum", "pszLog"), "returns a random number"))
    		.def("init", &CvRandom::init, "void (unsigned long int ulSeed)")
    		;
    }

    P.S.

    Тьфу Все дело было в том, что у меня в CivilizationIV.ini
    Стояла включенной запись случайных чисел в лог. Потому-то так эти функции и тормозили.
    Код:
    ; Enable rand event logging
    RandLog = 1
    Выключил её, игра резко прибавила в шустрости. Я ведь сколько времени то с этой опцией играл. Тьфу на меня.
    Код:
    ; Enable rand event logging
    RandLog = 0
    продвинь это сообщение в соцсеть:  
    Последний раз редактировалось Cansei; 01.09.2013 в 20:53.

  11. #31
    Цитата Сообщение от NeseryozniyVET Посмотреть сообщение

    У себя в моде я оптимизировал CvCity::getTeam(). Она по твоим скриншотам 4,73% жрет
    Код:
    TeamTypes CvCity::getTeam() const
    {
    //VET Optimization - begin /
    	//return GET_PLAYER(getOwnerINLINE()).getTeam();
    	return m_eTeam;
    //VET Optimization - end /
    }
    Может ее еще и инлайновой сделать ?
    Сделал по аналогии, добавил функции

    Код:
    TeamTypes CvCity::getTeam() const
    {
    	return m_eCityTeam;
    }
    
    void CvCity::updateTeamType()
    {
    	m_eCityTeam = GET_PLAYER(getOwnerINLINE()).getTeam();
    }

    updateTeamType() прописал в init, liberate и read. Так чтобы не сохранялась, а вычислялась при загрузке сейва. Вроде все идет, но не оставляет ощущение, что что-то забыл. Может ещё updateTeamType() нужен, какие вообще способы существуют для смены владельца города? Захват, дипломатия и освобождение?
    При захвате, как понимаю старый полностью уничтожается и создаётся новый, как его копия?


    После изменения, функция CvCity::getTeam() пропала из топа, но на верхние места вылезла другая CvCity::getOwner.
    CvTeam::getCompletedSpaceshipProjects вконец обнаглела, причем в половине случаев вызывает сама себя.
    продвинь это сообщение в соцсеть:  

  12. #32
    Похоже найден виновник многих несуразностей. Это функция CvUnit::getLayerAnimationPaths()

    Выглядит она вот так.

    Скрытый текст
    Код:
    void CvUnit::getLayerAnimationPaths(std::vector<AnimationPathTypes>& aAnimationPaths) const
    {
    	for (int i=0; i < GC.getNumPromotionInfos(); ++i)
    	{
    		PromotionTypes ePromotion = (PromotionTypes) i;
    		if (isHasPromotion(ePromotion))
    		{
    			AnimationPathTypes eAnimationPath = (AnimationPathTypes) GC.getPromotionInfo(ePromotion).getLayerAnimationPath();
    			if(eAnimationPath != ANIMATIONPATH_NONE)
    			{
    				aAnimationPaths.push_back(eAnimationPath);
    			}
    		}
    	}
    }


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

  13. #33
    Цитата Сообщение от Cansei Посмотреть сообщение
    Похоже найден виновник многих несуразностей. Это функция CvUnit::getLayerAnimationPaths(
    Ну во-первых GC.getNumPromotionInfos() нужно вывести за пределы цикла
    int iNumProm = GC.getNumPromotionInfos();
    for (int i=0; i < iNumProm; ++i)

    А во-вторых можно заменить булевый масив наличия прокачек у юнита, на масив существующих прокачек у юнита (и переделывать его при получении или потери прокачки) и переменную количества этих прокачек. Тогда код будет выглядеть так.
    Код:
    int iNumProm = m_iNumPromotions;//m_iNumPromotions - новая переменная у каждого юнита.
    PromotionTypes* peLoopProms = m_paePromotions;//m_paePromotions - новый масив взамен старого
    for (int i=iNumProm; i != 0; --i, ++peLoopProms)
    {
    	AnimationPathTypes eAnimationPath = (AnimationPathTypes) GC.getPromotionInfo(peLoopProms[0]).getLayerAnimationPath();
    	if(eAnimationPath != ANIMATIONPATH_NONE)
    	{
    		aAnimationPaths.push_back(eAnimationPath);
    	}
    }
    Эффект будет пропорционален количеству прокачек в моде.
    продвинь это сообщение в соцсеть:  
    Если новые технологии позволяют обходится без услуг простых людей - это прогресс, а если новые технологии позволяют обходится без услуг миллионеров и крупных компаний - это нарушение авторских прав.
    Мой мод

  14. #34
    А во-вторых можно заменить булевый масив наличия прокачек у юнита, на масив существующих прокачек у юнита (и переделывать его при получении или потери прокачки) и переменную количества этих прокачек. Тогда код будет выглядеть так.
    Спасибо, как-то так я и думал. Но при таких условиях по идее резко возрастет количество потребляемой памяти и время на запись/сохранение. Я вот думаю, как бы ввести int массив прокачек типа вектор, содержащие индекс прокачки в GC.getNumPromotionInfos() Но вот как конкретно это реализовать пока не знаю. Я C++ начал изучать только в июне, и то по книжкам, так что реального опыта в этом маловато.

    Похоже найден виновник многих несуразностей. Это функция CvUnit::getLayerAnimationPaths
    Там проблема в другом, там функция возвращает ссылку на пустой вектор, потому как LayerAnimationPaths отвечает за изменение внешнего вида юнита при получении прокачки. А таких прокачек не только в игре, но и в большинстве модов нет. Я специально смотрел в Master of Mana и Caveman2Space. Таких прокачек там не нашел. Я пробовал изменить функцию, убрав из неё ссылку на вектор. Но игра теперь не идет дальше главного меню. Буду думать дальше.
    продвинь это сообщение в соцсеть:  
    Последний раз редактировалось Cansei; 02.09.2013 в 17:04.

  15. #35
    Ну так предложеный мною метод и есть что-то типа вектора только быстрее и без лишних функций и переменных. Размер масива равен количеству прокачек у юнита, если прокачек нет - то просто нулевой указатель. В моем примере я предлагал масив PromotionTypes (32 бита), но если в моде количество прокачек не превышает число 255, то можно и unsigned char (8 бит) использовать или unsigned short (16 бит), если прокачек больше 255 и меньше 64 тисяч.
    продвинь это сообщение в соцсеть:  
    Если новые технологии позволяют обходится без услуг простых людей - это прогресс, а если новые технологии позволяют обходится без услуг миллионеров и крупных компаний - это нарушение авторских прав.
    Мой мод

  16. #36
    Цитата Сообщение от NeseryozniyVET Посмотреть сообщение
    Ну так предложеный мною метод и есть что-то типа вектора только быстрее и без лишних функций и переменных. Размер масива равен количеству прокачек у юнита, если прокачек нет - то просто нулевой указатель. В моем примере я предлагал масив PromotionTypes (32 бита), но если в моде количество прокачек не превышает число 255, то можно и unsigned char (8 бит) использовать или unsigned short (16 бит), если прокачек больше 255 и меньше 64 тисяч.
    А понятно, пардон не так понял. Так и сделаю. Я почему-то подумал о прикреплении к юниту всех его прокачек, как набора переменных. Совсем уже запутался с этими AnimationPathTypes и тем, как убедить функцию использовать анимацию юнита по умолчанию, если ни одна прокачка её не изменяет.
    продвинь это сообщение в соцсеть:  

  17. #37
    Цитата Сообщение от Cansei Посмотреть сообщение
    updateTeamType() прописал в init, liberate и read.
    В liberate прописывать не надо. Там идет вызов acquireCity, та вызывает initCity, а та init.
    продвинь это сообщение в соцсеть:  
    Если новые технологии позволяют обходится без услуг простых людей - это прогресс, а если новые технологии позволяют обходится без услуг миллионеров и крупных компаний - это нарушение авторских прав.
    Мой мод

  18. #38
    Цитата Сообщение от NeseryozniyVET Посмотреть сообщение
    В liberate прописывать не надо. Там идет вызов acquireCity, та вызывает initCity, а та init.
    Спасибо. Уберу. То есть достаточно только в init прописать? Ну и в read, если не сохранять. А этот TeamTypes для города, оно вообще много памяти требует? Как полноценный объект класса CvTeam?

    С LayerAnimationPaths долго маялся, разбирался с AnimationPaths. В итоге понял, что перемудрил и банально закомментил все лишнее. До меня дошло, что вызовы идут из самой функции, а не из exe. В итоге в списках этой функции теперь вообще не замечено. А раньше она со всеми вызовами жрала почти 5%. Все равно она даже в модах походу не используется. Тут может быть ошибка была, что вектор не был определен в функции, ну там std::vector<AnimationPathTypes> aAnimationPaths?

    Скрытый текст
    Код:
    void CvUnit::getLayerAnimationPaths(std::vector<AnimationPathTypes>& aAnimationPaths) const
    {
    	// for (int i=0; i < GC.getNumPromotionInfos(); ++i)
    	// {
    		// PromotionTypes ePromotion = (PromotionTypes) i;
    		// if (isHasPromotion(ePromotion))
    		// {
    			// AnimationPathTypes eAnimationPath = (AnimationPathTypes) GC.getPromotionInfo(ePromotion).getLayerAnimationPath();
    			// if(eAnimationPath != ANIMATIONPATH_NONE)
    			// {
    				// aAnimationPaths.push_back(eAnimationPath);
    			// }
    		// }
    	// }
    }


    Теперь вот новый враг CvCity::getOwner функция дерзкая больно, надо присмирить. Причем большая часть её вызовов почему-то идет из старой знакомой чертовки CvPlayerAI::AI_maxGoldPerTurnTrade. А ещё есть весьма наглая GetLocaleTime судя по названию она из питона? Почти полтора процента времени на неё уходит. Перенести бы это в dll.
    продвинь это сообщение в соцсеть:  

  19. #39
    Продолжаю углубляться в особенности исполнения функций. Специально прогонял через эти программки обычную версию, без модов. Так как играл без автоплея, то результат сильно отличался. Но вот проблемные функции по прежнему на месте. Тот же LayerAnimationPaths был замечен не раз, к тому же ещё вчера нашел в теме мода Planetfall случай когда она вообще приводила к вылету докапываясь до настроек карты. Что интересно на ихфанатиках вообще почти не заметил упоминания этой функции, походу либо они и не знают, что она странная, либо эти программки что-то не так показывают. Но судя по упоминанию в теме Planetfall и тому что обе программы показывают примерно одни и те же результаты, похоже где-то здесь и вправду подвох, найти бы ещё где.
    Я пока нашел три основные функции где точно виден подвох. Это за исключением уже побежденной LayerAnimationPaths , CvPlayerAI::AI_getGreeting и многократно упоминаемая CvPlayerAI::AI_maxGoldPerTurnTrade. Есть ещё около десятка других, но они не так заметны. CvPlayerAI::AI_getGreeting к примеру не только многократно вызывает сама себя, но и CvPlot::isLake зачем вообще функции выбирающей тип приветствия при диалоге с AI знать является ли тайл озером?

    Есть у меня пока гипотеза, что возникает это из-за какого-то бага в питон-составляющей, что присылает всякую ересь в фунции.
    Вот эта функция, уже упрощенная правда когда я комментирую все кроме последней строки, она пропадает из списков. Есть подозрение, что передаваемый PlayerTypes ePlayer идет как непойми что.
    Скрытый текст
    Код:
    DiploCommentTypes CvPlayerAI::AI_getGreeting(PlayerTypes ePlayer) const
    {
    	TeamTypes eWorstEnemy;
    
    	if (GET_PLAYER(ePlayer).getTeam() != getTeam())
    	{
    		eWorstEnemy = GET_TEAM(getTeam()).AI_getWorstEnemy();
    
    		if ((eWorstEnemy != NO_TEAM) && (eWorstEnemy != GET_PLAYER(ePlayer).getTeam()) && GET_TEAM(GET_PLAYER(ePlayer).getTeam()).isHasMet(eWorstEnemy) && (GC.getASyncRand().get(4) == 0))
    		{
    			if (GET_PLAYER(ePlayer).AI_hasTradedWithTeam(eWorstEnemy) && !atWar(GET_PLAYER(ePlayer).getTeam(), eWorstEnemy))
    			{
    				return (DiploCommentTypes)GC.getInfoTypeForString("AI_DIPLOCOMMENT_WORST_ENEMY_TRADING");
    			}
    			else
    			{
    				return (DiploCommentTypes)GC.getInfoTypeForString("AI_DIPLOCOMMENT_WORST_ENEMY");
    			}
    		}
    		else if ((getNumNukeUnits() > 0) && (GC.getASyncRand().get(4) == 0))
    		{
    			return (DiploCommentTypes)GC.getInfoTypeForString("AI_DIPLOCOMMENT_NUKES");
    		}
    		else if ((GET_PLAYER(ePlayer).getPower() < getPower()) && AI_getAttitude(ePlayer) < ATTITUDE_PLEASED && (GC.getASyncRand().get(4) == 0))
    		{
    			return (DiploCommentTypes)GC.getInfoTypeForString("AI_DIPLOCOMMENT_UNIT_BRAG");
    		}
    	}
    
    	return (DiploCommentTypes)GC.getInfoTypeForString("AI_DIPLOCOMMENT_GREETINGS");
    }
    продвинь это сообщение в соцсеть:  

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

    Аватар для Snake_B


    Регистрация
    14.09.2007
    Адрес
    Донецк-Камчатка....
    Сообщений
    13,314


    установил теме статус важная...

    to Cansei
    хотелось бы все таки, чтобы выкладывались исходники... а то много чего интересного делали, потом по каким-нибудь причинам пропадали...
    и все наработки вместе с ними...
    продвинь это сообщение в соцсеть:  

+ Ответить в теме
Страница 2 из 4 ПерваяПервая 123 ... ПоследняяПоследняя

Похожие темы

  1. Тайлы с ресами позначены с начала игры?
    от Taras_UA в разделе Civ5 - Игровые вопросы
    Ответов: 1
    Новое: 05.10.2010, 18:18
  2. Тактические уроки двух последних войн Ирака для общевойскового командира
    от Гость в разделе Разговоры обо всём, кроме Цивилизации
    Ответов: 2
    Новое: 18.03.2009, 16:57
  3. Уроки французского
    от BuDDaH в разделе Палаты команды Монархия MTDG2
    Ответов: 5
    Новое: 01.02.2007, 14:21
  4. Уроки C++
    от vpadlo в разделе Civ4 - Модная Цивилизация
    Ответов: 13
    Новое: 21.01.2007, 00:58
  5. Глючит 1.61 рус: с начала игры остается 10 ходов!
    от Mityay в разделе Civ4 - Технические вопросы
    Ответов: 1
    Новое: 17.07.2006, 13:51

Ваши права

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

free counters