Будем выяснять почему нерправильно высчитываются цены на ресурсы.
Вставь
CvWString szBuffer = CvWString::format(L"%c, Price%d, Percent%d, Profit%d", GC.getYieldInfo((YieldTypes)iYield).getChar(), aiPrices[iYield], getOverflowYieldSellPercent(), GET_PLAYER(getOwnerINLINE()).getSellToEuropeProfit(eYield, 1000));
gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_DEAL_CANCELLED", MESSAGE_TYPE_MINOR_EVENT, GC.getYieldInfo((YieldTypes)iYield).getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_YELOW"), getX_INLINE(), getY_INLINE(), true, true);
после строчки aiPrices[iYield] = getOverflowYieldSellPercent() * GET_PLAYER(getOwnerINLINE()).getSellToEuropeProfit(eYield, 1000);// Цена за 1000 единиц ресурса
з.ы. Замени цвет синего сообщения на желтый (синий шрифт на твоих скринах не разобрать) и поменяй в сообщениях /t на \t
Все понятно - формулу не правилно написал.
надо чтоб было
aiPrices[iYield] = (100 + getOverflowYieldSellPercent()) * GET_PLAYER(getOwnerINLINE()).getSellToEuropeProfit(eYield, 10);// Цена за 1000 единиц ресурса
а сейчас используется такая
aiPrices[iYield] = getOverflowYieldSellPercent() * GET_PLAYER(getOwnerINLINE()).getSellToEuropeProfit(eYield, 1000);// Цена за 1000 единиц ресурса
Компилирую.....
Готовою. Ход 1:
Цены (за 1000 единиц товара) соответствуют минимальным в Европе по всем позициям!
Продолжаю тест, но он идет достаточно медленно из-за кучи сообщений после каждого хода.
ЗЫ. Я тестирую вариант
Код:aiPrices[iYield] = (100 + getOverflowYieldSellPercent()) * GET_PLAYER(getOwnerINLINE()).getSellToEuropeProfit(eYield, 10);// Цена за 1000 единиц ресурса
Процесс идет очень медленно, но отключать проверку на каждом ходу я не хочу.
Поэтому для ускорения я добавил в город 100 лошадей (2 скаута)
Вот что было в городе перед удалением избытков
Цены такие: еда 2 (ее меньше, чем НЗ), шкуры 5, железная руда 2, лошади 6.
После удаления осталось
Самое главное в какой последовательности происходило удаление излишков со склада.
Первой исчезла самая дешевая (2 монеты) железная руда, 9 (что было на складе) плюс 3 (что произвели за ход). Итого потеря 12 единиц руды.
Вторыми исчезли шкуры (5 монет), тоже 9 плюс 3 единиц.
И наконец, последними исчезли самые дорогие (6 монет) лошади в количестве 18 штук.
Другими словами, удаление произошло ПРАВИЛЬНО!!!!
Я так понимаю getOverflowYieldSellPercent() это королевский налог, поэтому правильней, наверно, будет (100 - getOverflowYieldSellPercent()). Налог надо отнять, а не прибавить. Я прошлый раз ошибся. Но мы не продаем ресурсы, а выбираем самый дешевый, поэтому королевский налог можно не учитывать (зачем лишний раз напрягать проц), так как он одинаков для всех ресурсов.
Затрудняюсь сказать, что конкретно обозначает getOverflowYieldSellPercent(), но вряд ли это королевский налог. Для налога используется выражение getTaxRate().
-----------------------------------------------------------------------------------------------------
Дополнение:
Я посмотрел где и в какой связи в исходных кодах упоминается getOverflowYieldSellPercent().
OverflowYieldSellPercent связан со зданиями. Причем значение
встречается только для BUILDING_WAREHOUSE_EXPANSION. Все остальные здания имеют<iOverflowSellPercent>50</iOverflowSellPercent>
Таким образом, OverflowSellPercent означает процент от цены, за которую товары будут продаваться при переполнении склада, если построен самый "крутой" склад (BUILDING_WAREHOUSE_EXPANSION). На более простых складах при их переполнении товары просто исчезают без всякой оплаты. Если проще, их со склада воруют ....<iOverflowSellPercent>0</iOverflowSellPercent>
Второе упоминание getOverflowYieldSellPercent() есть в строке
Но это тоже понятно. ЕслиКод:int iProfit = getOverflowYieldSellPercent() * GET_PLAYER(getOwnerINLINE()).getSellToEuropeProfit(eYield, iLoss) / 100;
то и нет никакого дохода. Товар просто теряется.<iOverflowSellPercent>0</iOverflowSellPercent>
----------------------------------------------------------------------------------
Сегодня попробую вариант "с минусом":
Вчера при тестировании заметил одну странную особенность. Я пока не могу ее точно сформулировать, поэтому сделал три снимка.Код:aiPrices[iYield] = (100 - getOverflowYieldSellPercent()) * GET_PLAYER(getOwnerINLINE()).getSellToEuropeProfit(eYield, 10);// Цена за 1000 единиц ресурса
1.
2.
3.
Что конкретно кажется странным?
Во-первых, каждый снимок сделан после удаления избытков товара с переполненного склада. После, а не до!
Но, посмотри на количество товаров, имеющихся на складе (первая красная цифра после названия города):
1 снимок. 52 еды + 62 лошадей = 114
2. снимок: 48 еды + 58 лошадей = 106
3. снимок: 48 еды + 57 лошадей = 105
Непонятно, почему опорожнение склада за предыдущий ход идет не до максимально возможного минимума, равного 100?
Более того, опорожнение склада идет с учетом возможного роста запасов на складе в следующий ход.
А ведь получается именно так. Снова посмотри на снимки, но на этот раз на прибавку товара в следующий ход (зеленые цифры внизу):
1 снимок:
+4 еды + 3 шкуры + 3 руды = 14.
Это же значение получается, если (см. красные цифры о состоянии склада): 114 - 100 = 14
2 снимок:
+3 шкур + 3 руды = 6
Или 106 - 100 = 6
3 снимок:
+2 хлопка + 3 руды = 5
Или 105 - 100 = 5
Довольно-таки странная закономерность....
Все, getOverflowYieldSellPercent() нам вобще не нужно. Используй выражение
aiPrices[iYield] = GET_PLAYER(getOwnerINLINE()).getSellToEuropeProfit(eYield, 1000);// Цена за 1000 единиц ресурса
На счет бага
1) Замени строчку
int iTotalYields = getTotalYieldStored();// Количество всех ресурсов на складе
на
int iTotalYields;// Количество всех ресурсов на складе
2) А перед строчкой
if (bNEW_CAPACITY && (iTotalYields > iMaxCapacity))
добавь
iTotalYields = getTotalYieldStored();
Ошибка была из-за того, что сначала запоминалось количество всех ресурсов на складе и только потом происходило добавление ресурсов. Теперь же сначала подобавляются ресурсы и только потом запомнится количество всех ресурсов.
Скомпилировал Final Release CvGameCoreDLL.dll без проблем, запустил мод тоже нормально. Но на 4 ходу меня постоянно выбрасывало в десктоп.
Максимум, что я смог сделать, так это вытащить это сообщение:
Для поиска ошибки я скомпилировал Final Debug CvGameCoreDLL.dll. Запуск - нормально, но.... все работает ПРАВИЛЬНО и без сбоев.
- удаляется самый дешевый товар,
- удаление происходит до уровня вместимости склада, равной 100,
- неприкосновенный запас еды сохраняется неизменным.
Вот три снимка.
Скорость нормальная. Цены: еда 1, серебро 19, хлопок 5, руда 4 монеты.
Сейчас буду компилировать заново Final Release CvGameCoreDLL.dll и далее проверять уже с ним.
Дополнение:
Проверил с заново скомпилированным Final Release CvGameCoreDLL.dll. Все работает правильно и без сбоев. Поэтому сообщение об ошибке - удаляю.
Продолжаю тестирование....
Несколько дней назад, когда я компилировал CvGameCoreDLL.dll, то по дефолту у меня стояла опция Final Debug. С этим файлом я и запустил мод, но тут случилась ошибка, Microsoft Visual Studio .NET 2003, где я компилировал CvGameCoreDLL.dll, была еще включена и у меня на экране выскочило предложение выполнить Debug. Я естественно согласился и меня программа (Microsoft Visual Studio .NET 2003) вывела прямиком на строку в коде, вызвавшую вылет на десктоп.
Все получилось само собой, моей заслуги тут нет никакой. и поэтому сегодня, когда снова был вылет, я начал поиск возможной ошибки с создания Final Debug CvGameCoreDLL.dll, надеясь повторить свой предыдущий опыт. Это не помогло, потому что и Final Debug CvGameCoreDLL.dll, и скомпилированная повторно Final Release CvGameCoreDLL.dll, вылета на десктоп больше не давали. Все работало четко и без сбоев.
Я раньше тоже делал .exe.dmp файлы, но найти с их помощью ошибку смог лишь один раз. Не иначе тоже повезло.
Можно еще попробовать заменить число с бюстом на полосу прогресса (как в цивилизации), а подсказку оставить без изменений.
перед строчкой class CvMainInterface: добавить
Код:g_szStoredBarName = "StoredBar"
перед строчкой # EMPHASIZE TABLE добавить
iX, iY, iWeight, iHeight, заменить на числаКод:# CITY BUILDING STORED BAR screen.addStackedBarGFC(g_szStoredBarName, iX, iY, iWeight, iHeight, InfoBarTypes.NUM_INFOBAR_TYPES, WidgetTypes.WIDGET_HELP_POPULATION, -1, -1) screen.setStackedBarColors(g_szStoredBarName, InfoBarTypes.INFOBAR_STORED, gc.getInfoTypeForString("COLOR_GREAT_PEOPLE_STORED")) screen.setStackedBarColors(g_szStoredBarName, InfoBarTypes.INFOBAR_RATE, gc.getInfoTypeForString("COLOR_GREAT_PEOPLE_RATE")) screen.setStackedBarColors(g_szStoredBarName, InfoBarTypes.INFOBAR_RATE_EXTRA, gc.getInfoTypeForString("COLOR_EMPTY")) screen.setStackedBarColors(g_szStoredBarName, InfoBarTypes.INFOBAR_EMPTY, gc.getInfoTypeForString("COLOR_EMPTY")) screen.hide(g_szStoredBarName)
перед строчкой # CURRENT PRODUCTION BAR FILL добавить
Код:# CURRENT STORED BAR FILL fGrowthThreshold = float(pHeadSelectedCity.growthThreshold()) fCurrentBirthPoints = float(pHeadSelectedCity.currentBirthPoints()) iFirst = ((float(pHeadSelectedCity.getBirthPoints())) / fGrowthThreshold) screen.setBarPercentage(g_szStoredBarName, InfoBarTypes.INFOBAR_STORED, iFirst ) if (iFirst == 1): iSecond = fCurrentBirthPoints / fGrowthThreshold else: iSecond = (fCurrentBirthPoints / fGrowthThreshold) / (1 - iFirst) screen.setBarPercentage(g_szStoredBarName, InfoBarTypes.INFOBAR_RATE, iSecond ) screen.setBarPercentage(g_szStoredBarName, InfoBarTypes.INFOBAR_RATE_EXTRA, 0.0 )
после каждой строчки screen.hide("PopulationText") добавить
Код:screen.hide(g_szStoredBarName)
Я тоже думал о таком варианте. Надо попробовать несколько различных, включая конечно твой вариант с "полосой прогресса", посмотреть как это будет выглядеть на экране города, а затем выбрать наиболее оптимальный.
Пока же наверху экрана слишком много цифровой информации, а с учетом того, что я буду туда добавлять значения для Yield_Codex (цифра + значок), а затем и для Исследований (тоже цифра + значок), то будет крутой перебор. Уменьшить - невозможно, поэтому приходится каким-то образом "оптимизировать".
До "полоски прогресса" пока не дошел, потому что сначала хотел закончить свой вариант расположения информации вверху городского экрана.
Для начала я отвязал информацию о состоянии городского склада от названия города и перенес ее в левый верхний угол. Плюс добавил к ней иконку склада. Одновременно на освободившееся место рядом с названием города перенес данные об "очках рождаемости". Для них это самое подходящее место. В итоге получилось так:
Пока не идеально, но мне кажется выглядит уже поприличнее. Этот вариант работает стабильно и вылетов нет. Но нет и подсказки при наведении мышки на данные склада (зеленые цифры и иконка). А хотелось бы!
Для того, чтобы эта подсказка появилась я подредактировал пять файлов. Ниже я привожу новые участки кода, плюс строки до и после них, чтобы было ясно куда конкретно я внес добавления.
1. В CvEnums.h добавил
2. В CyEnumsInterface.cpp:Код:WIDGET_HELP_POPULATION, //KJ Warehouse START WIDGET_HELP_WAREHOUSE, //KJ Warehouse END WIDGET_HELP_REBEL
3. В CvDLLWidgetData.h:Код:.value("WIDGET_HELP_POPULATION", WIDGET_HELP_POPULATION) //KJ Warehouse START .value("WIDGET_HELP_WAREHOUSE", WIDGET_HELP_WAREHOUSE) //KJ Warehouse END .value("WIDGET_HELP_REBEL", WIDGET_HELP_REBEL)
4. В CvDLLWidgetData.cpp:Код:void parsePopulationHelp(CvWidgetDataStruct &widgetDataStruct, CvWStringBuffer &szBuffer); //KJ Warehouse START void parseWarehouseHelp(CvWidgetDataStruct &widgetDataStruct, CvWStringBuffer &szBuffer); //KJ Warehouse END void parseRebelHelp(CvWidgetDataStruct &widgetDataStruct, CvWStringBuffer &szBuffer);
иКод:case WIDGET_HELP_POPULATION: parsePopulationHelp(widgetDataStruct, szBuffer); break; //KJ Warehouse START case WIDGET_HELP_WAREHOUSE: parseWarehouseHelp(widgetDataStruct, szBuffer); break; //KJ Warehouse END case WIDGET_HELP_REBEL: parseRebelHelp(widgetDataStruct, szBuffer); break;
5. CvDLLWidgetData.h:Код:void CvDLLWidgetData::parsePopulationHelp(CvWidgetDataStruct &widgetDataStruct, CvWStringBuffer &szBuffer) { CvCity* pHeadSelectedCity; pHeadSelectedCity = gDLL->getInterfaceIFace()->getHeadSelectedCity(); if (pHeadSelectedCity != NULL) { // szBuffer.assign(gDLL->getText("TXT_KEY_MISC_FOOD_THRESHOLD", pHeadSelectedCity->getFood(), pHeadSelectedCity->growthThreshold())); //original, closed by KJ szBuffer.assign(gDLL->getText("TXT_KEY_MISC_BIRTHPOINTS_THRESHOLD", pHeadSelectedCity->getBirthPoints(), pHeadSelectedCity->currentBirthPoints(), pHeadSelectedCity->growthThreshold())); //KJ addon } } //KJ Warehouse START void CvDLLWidgetData::parseWarehouseHelp(CvWidgetDataStruct &widgetDataStruct, CvWStringBuffer &szBuffer) { CvCity* pHeadSelectedCity; pHeadSelectedCity = gDLL->getInterfaceIFace()->getHeadSelectedCity(); if (pHeadSelectedCity != NULL) { szBuffer.assign(gDLL->getText("TXT_KEY_MISC_WAREHOUSE", pHeadSelectedCity->getTotalYieldStored(), pHeadSelectedCity->getMaxYieldCapacity())); } } //KJ Warehouse END void CvDLLWidgetData::parseRebelHelp(CvWidgetDataStruct &widgetDataStruct, CvWStringBuffer &szBuffer) { if (widgetDataStruct.m_iData1 == 1) { CvCity* pHeadSelectedCity = gDLL->getInterfaceIFace()->getHeadSelectedCity(); if (pHeadSelectedCity != NULL) { szBuffer.assign(gDLL->getText("TXT_KEY_MISC_REBEL_HELP", pHeadSelectedCity->getRebelPercent())); } } else { szBuffer.assign(gDLL->getText("TXT_KEY_MISC_REBEL_HELP", GET_TEAM(GC.getGameINLINE().getActiveTeam()).getRebelPercent())); } }
Компилируем без ошибок, запускаем мод тоже без проблем. А дальше начинается какая-то мистика.Код:void parsePopulationHelp(CvWidgetDataStruct &widgetDataStruct, CvWStringBuffer &szBuffer); //KJ Warehouse START void parseWarehouseHelp(CvWidgetDataStruct &widgetDataStruct, CvWStringBuffer &szBuffer); //KJ Warehouse END void parseRebelHelp(CvWidgetDataStruct &widgetDataStruct, CvWStringBuffer &szBuffer);
Если я работаю мышкой и после наведения ею на кнопку "Continue" я получаю немедленный вылет на десктоп.
Если же я использую клавиатуру и просто нажимаю на этом экране кнопку "Enter", то могу спокойно продолжать игру.
Итак, стоим город, селим в нем пару жителей. Верхняя часть экрана после небольшого редактирования теперь выглядит так:
Я оставил только данные об изменении запасов на складе за ход. Все остальное - а именно текущее наполнение склада и его максимальная емкость - перемещены в подсказку.
Когда склад пополняется, это выглядит так
Когда склад опорожняется, так:
Можно конечно радоваться, ибо это именно тот вариант, что мне хотелось бы иметь, но на выходе меня ждут вторые грабли.
Снова, как и в случае с кнопкой "Continue", стоит мне навести курсор мыши на кнопку "Exit", следует моментальный вылет на десктоп.
И опять же, если выходить с городского экране не мышкой, а с помощью клавиатуры (кнопка "Esc"), то вылета нет и можно спокойно продолжать игру.
Лично я с таким встречаюсь впервые. Вчера весь вечер потратил на поиск этих "граблей", но так и не нашел.
WIDGET_HELP_WAREHOUSE прописал в кодах правильно, остальное тоже вроде бы все нормально. В конце концов весь с клавиатурой все же работает именно так, как и должно быть! А лишь при наведении мышькой на кнопки "Continue" и "Exit" следует немедленный вылет. Почему?