Перепутал BONUS с YIERLD.
Ну тогда первый вариант и заменить на BONUS_1 заменить на GC.getDefineINT("BONUS_1"). Но это плохой вариант, так как каждый раз при добавлении или изменении бонусов надо будет перекомпилировать DLL.
Лучше делать проверку по свойствам. По каким свойствам ты хочешь разделить ресурсы в подсказке ?
Если новые технологии позволяют обходится без услуг простых людей - это прогресс, а если новые технологии позволяют обходится без услуг миллионеров и крупных компаний - это нарушение авторских прав.
Мой мод
Список бонусов в принципе уже известен и вряд ли он будет сильно корректироваться в дальнейшем. По крайней мере перечисляемые ниже пункты 1, 2, 3 останутся неизменными.
Все бонусы разделяются на
1. обычные бонусы
Это табак, хлопок, зерно, сахар, бананы. Позже этот список будет расширен чаем, кофе, какао и т.д. Все это сеется или собирается игроком в обычном режиме.
Для этой категории бонусов на экране абсолютно достаточно той информации, что уже есть, то есть ничего не надо ни добавлять, ни изменять.
2. невосполнимые минеральные ресурсы
Сейчас это железная руда, серебро, золото и россыпное золото. Позже будут добавлены уголь, драгоценные камни, глина, сера и селитра.
Камень как бонус - неисчерпаемый ресурс.
Все эти исчерпаемые бонусные ресурсы сейчас прекрасно описываются той подсказкой, что я приводил выше, а именно:
Тут сверху вниз идут:
С ними все в порядке, поэтому и для них менять или править ничего не надо.Название ресурса (Россыпное золото)
Текуший запас месторождения: 40
Ресурс исчерпаемый
3. воспроизводимые животные и растительные ресурсы
В оригинальной версии игры это, к примеру BONUS_DEER, BONUS_FUR и продукты моря: BONUS_CRAB и BONUS_FISH. Позже в этот список будут добавлены прежде всего обычная древесина (BONUS_LUMBER), ценные породы древесины (BONUS_VALUABLE_WOOD) и слоновая кость (BONUS_IVORY).
Сейчас воспроизводимые животные и растительные ресурсы работают по предельно простому принципу.
На первом ходу есть некий начальный запас этого ресурса.
Если клетка, на которой находится данный воспроизводимый ресурс, находится за пределами города, то данный ресурс каждый ход увеличивается, к примеру на 2. (эффект "дикой" природы, пока еще не тронутой цивилизацией)
Если клетка находится в пределах городской черты, но не обрабатывается - то только на 1, (сказывается влияние близлежащего города.)
Если клетка с данным бонусом обрабатывается в данном городе, то запас уменьшается на количество извлеченного ресурса и увеличивается на 1. При активной добыче шкур или древесины в какой-то момент наступает полное истощение бонусной клетки, поскольку скорость воспроизводства заведомо меньше скорости добычи. Бонус просто исчезает с карты, как это происходит сейчас с исчерпаемыми минеральными ресурсами.
Эта логика прекрасно работает и именно для данной категории "Воспроизводимых животных и растительных ресурсов" очень хотелось бы изменить подсказку.
А для этого надо как-то добраться (???) в CvGameTextMgr.cpp до TXT_KEY_BONUS_STATUS и TXT_KEY_AMOUNT_BONUS и разделить их на две части
и новые1. TXT_KEY_BONUS_STATUS и TXT_KEY_AMOUNT_BONUS - для невосполнимых минеральных ресурсов (что уже есть)
Вопрос только как это сделать?2. TXT_KEY_BONUS_STATUS_2 и TXT_KEY_AMOUNT_BONUS_2 - для воспроизводимых животных и растительных ресурсов.
У меня сейчас нет под рукой компилятора и игры, поэтому мне сложно воспроизвести по памяти результат, но почти что такой вариант я точно пробовал. Моя строка выглядела так:
В этом случае я мог скомилировать CvGameCoreDLL.dll, но подсказки вообще исчезли. Вариант типаКод:if (eBonus == (BonusTypes)GC.getDefineINT("BONUS_GOLD"))
я, насколько мне помнится, не пробовал. Сегодня вечером проверю и его, а затем отпишу что получилось.Код:if (eBonus == GC.getDefineINT("BONUS_GOLD"))
Перекомпиляция и дополнительная правка уже готового кода меня совершенно не пугает. Это потребует несколько минут времени.
Нашел в своих заметках ответ компилятора.
Если
то компилятор выдает лишь одно сообщение об ошибке:Код:if (eBonus == GC.getBonusInfo(BONUS_SILVER))
Дальнейшая компиляция невозможна.Код:CvGameCoreDLL\CvGameTextMgr.cpp(2282): error C2065: 'BONUS_SILVER' : undeclared identifier
Нашел решение!
Профессиональных программистов и людей, хоть немного знакомым с С++, убедительно прошу далее не читать, а если все же прочитаете, то не плеваться. Лучше вспомните табличку в американских кабаках времен Дикого Запада.
"В пианиста не стрелять! Он играет как умеет!"
Итак снимки с результатами.
Серебро (невосполнимый минеральный ресурс)
Рыба (один из воспроизводимых ресурсов)
Найденное решение наверняка идиотское с точки зрения программирования. но оно работает!
Для получения желаемого результата надо было условия выбора прописать так:
то тогда читаются "TXT_KEY_BONUS_STATUS" и "TXT_KEY_AMOUNT_BONUS"Код:if ((eBonus == 5) || (eBonus == 6))
А если
то тогда читаются "TXT_KEY_BONUS_STATUS_2" и "TXT_KEY_AMOUNT_BONUS_2".Код:if ((eBonus == 3) || (eBonus == 4))
Номера после "eBonus ==" соответствуют порядковым номерам соответствующих бонусов в CIV4BonusInfos.xml, если начинать счет с нуля.
Наверняка эти же цифры можно описать покрасивше, но "пианист" этого не Шмог сделать. Сорри!
BONUS_SILVER должно быть в кавычках
Второй тип ресурсов определяется условиями
if (GC.getBonusInfo(eBonus).getMaxAmount() > 0)
или
if (pPlot->getAmount() > 0)
Аналогичным образом можно определять и третий тип ресурса.
Создаешь новый параметр для бонусов по аналогии с моим максимальным количеством iMaxAmount. Что-то типа пополняемость, естественное восстановление и т.д. (только на английском). Этот новый параметр будет отвечать за пополнение месторождения (популяции) ресурса.
Если новые технологии позволяют обходится без услуг простых людей - это прогресс, а если новые технологии позволяют обходится без услуг миллионеров и крупных компаний - это нарушение авторских прав.
Мой мод
Я пробовал различные варианты для eBonus == , в том числе и эти два (как с кавычками, так и без).
Код:if (eBonus == GC.getBonusInfo("BONUS_SILVER"))В самом лучшем случае файл компилируется, но подсказка на экране не появляется. Собственно поэтому я и остановился на простейшем варианте написания условий для eBonus ==.Код:if (eBonus == GC.getDefineINT("BONUS_SILVER"))
Действительно, в самом начале этого раздела в CvGameTextMgr.cpp мы видим:
Что означает выражение "if (eBonus != NO_BONUS)"?Код:eBonus = pPlot->getBonusType(); if (eBonus != NO_BONUS) и далее тра-ля-ля условия.
В самом общем виде - "Если есть бонус". А если прочитать его по частям, то получим: "Если неверно условие, что нет бонуса". В данном случае NO_BONUS означает для меня "нет бонуса", но программа его воспринимает как -1. Но -1 это число, поэтому совершенно разумно было предположить, что программа готова принять вместо -1 некие иные цифры.
Но что это могут быть за цифры и откуда они возмуться?
Я предположил, что цифры - номера имеющихся в игре бонусов, а они могут взяться только из CIV4BonusInfos.xml. При этом цифры должны означать порядковый номер бонуса при расчете сверху вниз, начиная с нуля. Такое правило жестко действует в CIV4YieldInfos.xml, поэтому разумно было допустить, что и для случая с бонусами оно также будет действовать.
Когда я проверил эти предположение, введя
иКод:// KJ comments: for Exhaustible bonus resources if ((eBonus == 5) || (eBonus == 6) || (eBonus == 7) || (eBonus == 12)) //List of Exhaustible bonus resources according to CIV4BonusInfos.xml: // 5 - BONUS_SILVER // 6 - BONUS_GOLD // 7 - BONUS_PLACER_GOLD //12 - BONUS_IRON
то все заработало, как и требовалось. Пара снимков в предыдущем моем сообщении сделана с уже скомпилированного мода.Код:// KJ comments: for Renewable bonus resources if ((eBonus == 1) || (eBonus == 3) || (eBonus == 4) || (eBonus == 9)) //List of Renewable bonus resources according to CIV4BonusInfos.xml: // 1 - BONUS_DEER // 3 - BONUS_CRAB // 4 - BONUS_FISH // 9 - BONUS_FUR
В готовом виде этот участок кода выглядит так:
Единственное неудобство, что надо четко помнить о порядковом номере при добавлении новых бонусов и их вводить надо после уже введенных. Если же будут добавлены такие бонусы, которые подпадут под условия 2 (исчерпаемые) или 3 (возобновляемые ресурсы), то их при любых нужно будет специально прописывать в этом разделе CvGameTextMgr.cpp. Но это работа на пару минут.Код:eBonus = pPlot->getBonusType(); // if (eBonus != NO_BONUS) //original; closed by KJ //KJ addon START // KJ comments: for Exhaustible bonus resources if ((eBonus == 5) || (eBonus == 6) || (eBonus == 7) || (eBonus == 12)) //List of Exhaustible bonus resources according to CIV4BonusInfos.xml: // 5 - BONUS_SILVER // 6 - BONUS_GOLD // 7 - BONUS_PLACER_GOLD //12 - BONUS_IRON { szTempBuffer.Format(L"%c " SETCOLR L"%s" ENDCOLR, GC.getBonusInfo(eBonus).getChar(), TEXT_COLOR("COLOR_HIGHLIGHT_TEXT"), GC.getBonusInfo(eBonus).getDescription()); szString.append(NEWLINE); szString.append(szTempBuffer); // VET AmountResourses - begin 1/2 if (pPlot->getAmount() > 0) // если ресурс исчерпаемый { szString.append(CvWString::format(L"\n%c", gDLL->getSymbolID(BULLET_CHAR))); //added by KJ szString.append(gDLL->getText("TXT_KEY_BONUS_STATUS")); //added by KJ szTempBuffer.Format(L" %d", pPlot->getAmount()); szString.append(szTempBuffer); // добавляем количество ресурсов в подсказку на экране szString.append(CvWString::format(L"\n%c", gDLL->getSymbolID(BULLET_CHAR))); //added by KJ szString.append(gDLL->getText("TXT_KEY_AMOUNT_BONUS")); //added by KJ } } // VET AmountResourses - end 1/2 // KJ comments: for Renewable bonus resources if ((eBonus == 1) || (eBonus == 3) || (eBonus == 4) || (eBonus == 9)) //List of Renewable bonus resources according to CIV4BonusInfos.xml: // 1 - BONUS_DEER // 3 - BONUS_CRAB // 4 - BONUS_FISH // 9 - BONUS_FUR { szTempBuffer.Format(L"%c " SETCOLR L"%s" ENDCOLR, GC.getBonusInfo(eBonus).getChar(), TEXT_COLOR("COLOR_HIGHLIGHT_TEXT"), GC.getBonusInfo(eBonus).getDescription()); szString.append(NEWLINE); szString.append(szTempBuffer); // VET AmountResourses - begin 1/2 if (pPlot->getAmount() > 0) // если ресурс исчерпаемый { szString.append(CvWString::format(L"\n%c", gDLL->getSymbolID(BULLET_CHAR))); //added by KJ szString.append(gDLL->getText("TXT_KEY_BONUS_STATUS_2")); //added by KJ szTempBuffer.Format(L" %d", pPlot->getAmount()); szString.append(szTempBuffer); // добавляем количество ресурсов в подсказку на экране szString.append(CvWString::format(L"\n%c", gDLL->getSymbolID(BULLET_CHAR))); //added by KJ szString.append(gDLL->getText("TXT_KEY_AMOUNT_BONUS_2")); //added by KJ } // VET AmountResourses - end 1/2 } //KJ addon END
Безусловно можно, но это довольно сложно и по-моему излишне.
Я поступил намного проще.
В CvPlot.cpp у тебя есть такой участок кода:
Здесь ты вычисляешь уменьшения исчерпаемого ресурса за ход. Для этого, как я понимаю, вводится временная переменная iAmountYields. Сразу извиняюсь с терминами, возможно они не совсем правильны и на русский переводятся как-то иначе. Тем не менее я решил "перехватить" расчет с помощью iAmountYields.Код:void CvPlot::doTurn() { .... // VET AmountResourses - begin 2/24 BonusTypes eBonus = (BonusTypes)m_eBonusType; if (eBonus != NO_BONUS) // если на тайле есть месторождение ресурса { CvBonusInfo& kBonusInfo = GC.getBonusInfo(eBonus); if (kBonusInfo.getMaxAmount() > 0) // если ресурс исчерпуемый { YieldTypes eYield; for (int i = 0; i < NUM_YIELD_TYPES; i++) // перебираем отдачу { eYield = (YieldTypes)i; // тип отдачи if (kBonusInfo.getYieldChange(eYield) > 0) // если ресурс увеличивает отдачу { int iAmountYields = 0; // расход месторождения за этот ход if (getPlotCity() != NULL) // если на тайле город { iAmountYields = kBonusInfo.getYieldChange(eYield); } else { CvCity* pWorkingCity = getWorkingCity(); if ((pWorkingCity != NULL) && (pWorkingCity->getUnitWorkingPlot(this) != NULL)) // если тайл в пределах городских границ и на тайле трудится горожанин { iAmountYields = calculateYield(eYield, false, /*OnlyBonus*/true); } } if (iAmountYields > 0) // если есть расход месторождения { setAmount(m_iAmount - iAmountYields); // уменьшаем запас месторождения if (m_eBonusType != NO_BONUS) // если месторождение не израсходовано { if (m_iAmount < iAmountYields) // если в месторождении меньше ресурса чем полная отдача ресурса { updateYield(true); // пересчитуем отдачу от тайла } } } } } } } // VET AmountResourses - end 2/24 .... }
В твоем варианте iAmountYields - расход месторождения за этот ход. От себя добавлю "для исчерпаемого минерального ресурса".
Что сделал я? Добавил свою пару переменных после int iAmountYields
Естественно увеличение запаса ресурса возможно только для восполняемого ресурса. Причем здесь я сразу же разделил эту прибавку на два возможных варианта: в пределах города и за пределами города.Код:int iAmountYields = 0; // расход месторождения за этот ход //KJ addon Renewable resourses START int iAmountYields2 = 0; // увеличение запаса ресурса за этот ход для тайлов внутри городской черты int iAmountYields3 = 0; // увеличение запаса ресурса за этот ход за пределами городской черты //KJ addon Renewable resourses END
В итоге приведенный участок кода теперь выглядит так:
Дополнительные пояснения даны по-русски прямо в самом коде, поэтому детально их расписывать вряд ли необходимо.Код:void CvPlot::doTurn() { .... // VET AmountResourses - begin 2/24 BonusTypes eBonus = (BonusTypes)m_eBonusType; if (eBonus != NO_BONUS) // если на тайле есть месторождение ресурса { CvBonusInfo& kBonusInfo = GC.getBonusInfo(eBonus); if (kBonusInfo.getMaxAmount() > 0) // если ресурс исчерпаемый { YieldTypes eYield; for (int i = 0; i < NUM_YIELD_TYPES; i++) // перебираем отдачу { eYield = (YieldTypes)i; // тип отдачи if (kBonusInfo.getYieldChange(eYield) > 0) // если ресурс увеличивает отдачу { int iAmountYields = 0; // расход месторождения за этот ход //KJ addon Renewable resourses START int iAmountYields2 = 0; // увеличение запаса ресурса за этот ход для тайлов внутри городской черты int iAmountYields3 = 0; // увеличение запаса ресурса за этот ход за пределами городской черты //KJ addon Renewable resourses END if (getPlotCity() != NULL) // если на тайле город { iAmountYields = kBonusInfo.getYieldChange(eYield); } if (CvCity* pWorkingCity = getWorkingCity()) { if ((pWorkingCity != NULL) && (pWorkingCity->getUnitWorkingPlot(this) != NULL)) // если тайл в пределах городских границ и на тайле трудится горожанин //KJ addon Renewable resourses START { if ((eYield == YIELD_SILVER) || (eYield == YIELD_ORE) || (eYield == YIELD_GOLD)) // минеральные ресурсы { iAmountYields = calculateYield(eYield, false, /*OnlyBonus*/true); // уменьшения запаса ресурса происходит НА ВЕЛИЧИНУ БОНУСА } if ((eYield == YIELD_FUR) || (eYield == YIELD_FOOD)) // Renewable resourses YIELD_FUR and YIELD_FOOD (ONLY BONUS_CRAB and ) { iAmountYields = calculateYield(eYield, false) + 1; // уменьшения запаса ресурса происходит на величину БОНУСА + БАЗОВАЯ ОТДАЧА с тайла, + 1 для корректировки } } //KJ comments START /* Если тайл в пределах городских границ, НО на тайле НЕ трудится горожанин. Ввести корректировку (псевдо-коэффициент) для возобновляемых ресурсов Этот псевдо-коэффициент РАВЕН НУЛЮ для исчерпаемых минеральных ресурсов и БОЛЬШЕ НУЛЯ для возобновляемых ресурсов */ else { if ((eYield == YIELD_SILVER) || (eYield == YIELD_ORE) || (eYield == YIELD_GOLD)) // минеральные ресурсы невосполнимы { iAmountYields2 = 0; //увеличения запаса ресурса НЕ происходит } else { iAmountYields2 = calculateYield(eYield, false, /*OnlyBonus*/true) * 1 / 2 - 2; // увеличение запаса ресурса на +1 за счет восстанавления в пределах городской черты } } //KJ addon END } //KJ addon START /* Если тайл ЗА ПРЕДЕЛАМИ городских границ. Введена корректировка (псевдо-коэффициент) для возобновляемых ресурсов, равная +2. Этот псевдо-коэффициент РАВЕН НУЛЮ для исчерпаемых минеральных ресурсов и БОЛЬШЕ НУЛЯ для возобновляемых ресурсов */ if (getPlotCity() == NULL) // если на тайле НЕТ города { if ((eYield == YIELD_SILVER) || (eYield == YIELD_ORE) || (eYield == YIELD_GOLD)) // минеральные ресурсы невосполнимы { iAmountYields3 = 0; } else // возобновляемые ресурсы восстанавливаются со скоростью iAmountYields3 { iAmountYields3 = 2; // увеличение запаса ресурса на +2 за счет восстанавления за пределами городской черты } } //KJ addon END //KJ addon START if ((iAmountYields > 0) || (iAmountYields2 > 0) || (iAmountYields3 > 0)) // если есть расход ИЛИ приход месторождения { //корректировка запаса ресурса в зависимости от iAmountYields, iAmountYields2 и iAmountYields3 setAmount(m_iAmount - iAmountYields + iAmountYields2 + iAmountYields3); // уменьшаем запас месторождения + увеличиваем за счет восстанавления для животных и растительных ресурсов //KJ addon END if (m_eBonusType != NO_BONUS) // если месторождение не израсходовано { if (m_iAmount < iAmountYields) // если в месторождении меньше ресурса, чем полная отдача ресурса { updateYield(true); // пересчитываем отдачу от тайла } } } } } } } // VET AmountResourses - end 2/24 .... }
В итоге вместо уменьшения минерального ресурса
мы получаем дифференцированный ответ:Код:setAmount(m_iAmount - iAmountYields)
когда минеральные ресурсы уменьшаются как и должно быть, а восполнимые ресурсы увеличиваются в зависимости от того где они - в пределах городской черты или вне ее. Псевдо-коэффициенты при расчетах iAmountYields2 и iAmountYields3 я подобрал экспериментально, поскольку величины бонусов известны заранее.Код://корректировка запаса ресурса в зависимости от iAmountYields, iAmountYields2 и iAmountYields3 setAmount(m_iAmount - iAmountYields + iAmountYields2 + iAmountYields3); // уменьшаем запас месторождения + увеличиваем за счет восстанавления для животных и растительных ресурсов
Все работает так, как и планировалось. Плюс все предельно просто, а ошибок я пока не нашел.
Ты не учел вариант когда в месторождении ресурса меньше чем отдача от бонуса и после пополнения ресурса стало больше или равно чем отдача от бонуса
И я все-таки рекомендую сделать новый параметр для бонуса естественное пополнение. Во-первых не надо будет помнить порядок ресурсов в XML, а во-вторых - можно для каждого бонуса делать разныое пополнение.Код:void CvPlot::doTurn() { .... // VET AmountResourses - begin 2/24 BonusTypes eBonus = (BonusTypes)m_eBonusType; if (eBonus != NO_BONUS) // если на тайле есть месторождение ресурса { CvBonusInfo& kBonusInfo = GC.getBonusInfo(eBonus); if (kBonusInfo.getMaxAmount() > 0) // если ресурс исчерпаемый { YieldTypes eYield; for (int i = 0; i < NUM_YIELD_TYPES; i++) // перебираем отдачу { eYield = (YieldTypes)i; // тип отдачи if (kBonusInfo.getYieldChange(eYield) > 0) // если ресурс увеличивает отдачу { int iOldAmount = m_iAmount; // запас месторождения до изменений int iAmountYields = 0; // расход месторождения за этот ход //KJ addon Renewable resourses START int iAmountYields2 = 0; // увеличение запаса ресурса за этот ход для тайлов внутри городской черты int iAmountYields3 = 0; // увеличение запаса ресурса за этот ход за пределами городской черты //KJ addon Renewable resourses END if (getPlotCity() != NULL) // если на тайле город { iAmountYields = kBonusInfo.getYieldChange(eYield); } if (CvCity* pWorkingCity = getWorkingCity()) { if ((pWorkingCity != NULL) && (pWorkingCity->getUnitWorkingPlot(this) != NULL)) // если тайл в пределах городских границ и на тайле трудится горожанин //KJ addon Renewable resourses START { if ((eYield == YIELD_SILVER) || (eYield == YIELD_ORE) || (eYield == YIELD_GOLD)) // минеральные ресурсы { iAmountYields = calculateYield(eYield, false, /*OnlyBonus*/true); // уменьшения запаса ресурса происходит НА ВЕЛИЧИНУ БОНУСА } if ((eYield == YIELD_FUR) || (eYield == YIELD_FOOD)) // Renewable resourses YIELD_FUR and YIELD_FOOD (ONLY BONUS_CRAB and ) { iAmountYields = calculateYield(eYield, false) + 1; // уменьшения запаса ресурса происходит на величину БОНУСА + БАЗОВАЯ ОТДАЧА с тайла, + 1 для корректировки } } //KJ comments START /* Если тайл в пределах городских границ, НО на тайле НЕ трудится горожанин. Ввести корректировку (псевдо-коэффициент) для возобновляемых ресурсов Этот псевдо-коэффициент РАВЕН НУЛЮ для исчерпаемых минеральных ресурсов и БОЛЬШЕ НУЛЯ для возобновляемых ресурсов */ else { if ((eYield == YIELD_SILVER) || (eYield == YIELD_ORE) || (eYield == YIELD_GOLD)) // минеральные ресурсы невосполнимы { iAmountYields2 = 0; //увеличения запаса ресурса НЕ происходит } else { iAmountYields2 = calculateYield(eYield, false, /*OnlyBonus*/true) * 1 / 2 - 2; // увеличение запаса ресурса на +1 за счет восстанавления в пределах городской черты } } //KJ addon END } //KJ addon START /* Если тайл ЗА ПРЕДЕЛАМИ городских границ. Введена корректировка (псевдо-коэффициент) для возобновляемых ресурсов, равная +2. Этот псевдо-коэффициент РАВЕН НУЛЮ для исчерпаемых минеральных ресурсов и БОЛЬШЕ НУЛЯ для возобновляемых ресурсов */ if (getPlotCity() == NULL) // если на тайле НЕТ города { if ((eYield == YIELD_SILVER) || (eYield == YIELD_ORE) || (eYield == YIELD_GOLD)) // минеральные ресурсы невосполнимы { iAmountYields3 = 0; } else // возобновляемые ресурсы восстанавливаются со скоростью iAmountYields3 { iAmountYields3 = 2; // увеличение запаса ресурса на +2 за счет восстанавления за пределами городской черты } } //KJ addon END //KJ addon START if ((iAmountYields > 0) || (iAmountYields2 > 0) || (iAmountYields3 > 0)) // если есть расход ИЛИ приход месторождения { //корректировка запаса ресурса в зависимости от iAmountYields, iAmountYields2 и iAmountYields3 setAmount(m_iAmount - iAmountYields + iAmountYields2 + iAmountYields3); // уменьшаем запас месторождения + увеличиваем за счет восстанавления для животных и растительных ресурсов //KJ addon END if (m_eBonusType != NO_BONUS) // если месторождение не израсходовано { if ((m_iAmount < iAmountYields) || (iOldAmount < iAmountYields)) // если в месторождении стало или было меньше ресурса, чем полная отдача ресурса { updateYield(true); // пересчитываем отдачу от тайла } } } } } } } // VET AmountResourses - end 2/24
Если новые технологии позволяют обходится без услуг простых людей - это прогресс, а если новые технологии позволяют обходится без услуг миллионеров и крупных компаний - это нарушение авторских прав.
Мой мод
Большое спасибо за уточнение. Я посмотрю, что смогу сделать для восполнимого ресурса.
Правда для начала я попытаюсь понять почему в CIV4UnitInfos.xml не работает этот участок
где iYieldChange есть некая величина МИНУС Х.Код:<YieldChanges> <YieldChange> <YieldType>YIELD_ORE</YieldType> <iYieldChange>-Х</iYieldChange> </YieldChange> </YieldChanges>
Я планирую с одной стороны унифицировать профессию "шахтера", поручив ему одному добывать все минеральные ресурсы, где необходима шахта. А это железная руда, серебро, золото (но не россыпное), и новые ресурсы типа угля, серы, соли и т.д. Все операции должен выполнять один юнит, причем только при условии построения шахты.
С другой стороны требуется исключить возможность добычи минеральных ресурсов остальными юнитами. Раньше это было сделать очень просто, введя в CIV4UnitInfos.xml к примеру условие, где Х = 3:
Если на бонусной клетке было 3 единицы, к примеру руды, то колонист добывать ее не мог. У него вообще не было профессии шахтера.Код:<YieldChanges> <YieldChange> <YieldType>YIELD_ORE</YieldType> <iYieldChange>-3</iYieldChange> </YieldChange> </YieldChanges>
Такая возможность была в оригинальной версии, но при введении исчерпаемых ресурсов исчезла. Поэтому я ищу возможность восстановить утраченное, но при этом не загубить уже прекрасно работающий вариант исчерпаемых ресурсов.
Если новые технологии позволяют обходится без услуг простых людей - это прогресс, а если новые технологии позволяют обходится без услуг миллионеров и крупных компаний - это нарушение авторских прав.
Мой мод
Вот это и странно....
Я ввожу ограничение на возможность добычи руды для юнита, ставя в CIV4UnitInfos.xml, к примеру, -4, что фактически означает полный запрет на добычу руды, но юнит как ни в чем не бывало продолжает добывать руду в количествах, определяемых в CIV4BonusInfos.xml:
Для городских профессий (те, что в зданиях) все работает штатно. Если для этого же самого юнита я ставлю в CIV4UnitInfos.xml, к примеру, -2 на производство колоколов, то данный юнит действительно производит на 2 колокола меньше, чем должен.Код:<YieldChanges> <YieldIntegerPair> <YieldType>YIELD_ORE</YieldType> <iValue>3</iValue> </YieldIntegerPair> </YieldChanges>
А вот для полевых профессий - типа шахтера - это почему-то не работает....
Небольшое пояснение относительно того, для чего это надо.
В оригинальной версии любой юнит мог производить все что угодно. Можно было, к примеру, загнать рыбака или администратора (UNIT_STATESMAN) в шахту и они добывали бы одинаковое количество руды. Можно в эту же шахту было направить шахтера и тогда он добывал бы в 2 раза больше руды. На первый взгляд вроде бы логично.
Но наскольно разумно такое решение?
Абсолютно невозможно представить работающего в шахте администратора (UNIT_STATESMAN). Или возвращаясь в наше время - нынешних президентов, премьеров или кого-нибудь из их многочисленной челяди во власти, если конечно их туда не отправили по решению суда. Но даже и в этом случае, их производительность по определению должна быть очень низкой, практически нулевой, так как они не приспособлены и не обучены для такой работы.
Каков же выход? Очень простой. Нужно четко разделить все профессии на три класса.
Полевые профессии - шахтер, рыбак, пахарь и т.д.
Городские мастеровые - плотник, кузнец, винодел и т.д.
Высшее сословие - администратор и священник.
Для первой категории юнитов, владеющих полевыми профессиями, ввести большие минусы на занятие должностей администратора или священника, к примеру -2. Это будет означать, что рыбак может работать в качестве администратора, но его отдача как работника, будет очень низкой. За примерами из нашей жизни ходить далеко не надо. Бывший президент, а ныне премьер России Медведев. По первой профессии - дворник, но оказавшись наверху административной лестницы, запомнился переводом стрелок часов, "отливанием в граните" и массой иных глупостей.
Для представителей же высших сословий напротив, нужно ввести ограничение при их работе в "полевых" условиях, вводя большие минусы при работе в поле, на шахте или в море (рыбалка).
Для городских мастеровых должен быть некий промежуточный вариант, когда они наиболее производительны только в своей должности, а все что профессионально выше или ниже них, то идет с минимальным минусом (-1).
Собственно для этого мне и нужно работающий механизм введения минусов. Пока же он работает только для городских профессий.
Как говорил Семен Семенович Горбунков из "Бриллиантовой руки", выбирая халат в комиссионке.
- А у Вас есть точно такой же, но с перламутровыми пуговицами?
- К сожалению, нет.
- Будем искать....
Ну и я продолжу поиск причины ...![]()
Вот кстати еще одна небольшая иллюстрация к описанной выше проблеме.
- Бонусная клетка ТАБАК.
- BONUS_TOBACCO не подпадает ни под какие ограничения. Это естественно ни минеральный исчерпаемый, ни восполняемый растительный ресурс. Табак - самый обычный бонус.
Для него в CIV4BonusInfos.xml имеем:
Для колониста я исключительно для пробы ввожу в CIV4UnitInfos.xml:Код:<Type>BONUS_TOBACCO</Type> <Description>TXT_KEY_BONUS_TOBACCO</Description> <Civilopedia>TXT_KEY_YIELD_TOBACCO_PEDIA</Civilopedia> <ArtDefineTag>ART_DEF_BONUS_TOBACCO</ArtDefineTag> <BuildingType>BUILDING_BONUS_TOBACCO</BuildingType> <YieldChanges> <YieldIntegerPair> <YieldType>YIELD_TOBACCO</YieldType> <iValue>3</iValue> </YieldIntegerPair> </YieldChanges> <iAIObjective>0</iAIObjective> .........
Код:<YieldChanges> <YieldChange> <YieldType>YIELD_TOBACCO</YieldType> <iChange>-2</iChange> </YieldChange> </YieldChanges>
То есть в итоге должно быть
+3 с бонуса, - 2 с юнита, работающего на сборе табака. Этот юнит должен собирать только 1 единицу табака с бонусной клетки.+3 - 2 = 1
Однако в реальности колонист может собирать 3 единицы табака, то есть то количество, что прописано в CIV4BonusInfos.xml.
На снимке снизу я специально впечатал участок с описанием запасов табака на бонусной клетке.
Это подтверждает, что сейчас ни один из "полевых" бонусов не может быть уменьшен через CIV4UnitInfos.xml.
Дополнено: Клетка, где колонист может собирать табак, единственная в пределах данного города. Других клеток с табаком - нет
А ты попробуй отдачу ресурсов сделать маленькую, а спецам побышеный бонус при обработке.
Если новые технологии позволяют обходится без услуг простых людей - это прогресс, а если новые технологии позволяют обходится без услуг миллионеров и крупных компаний - это нарушение авторских прав.
Мой мод
Итак, мне удалось-таки подкорректировать исходные коды мода таким образом, чтобы с одной стороны восстановить утраченные возможности введения минусов для юнитов, а с другой не разрушить уже прекрасно работающие ископаемые ресурсы. Для этого пришлось довольно значительно подправить один из разделов CvPlot.cpp, а именноВ конечном (измененном) виде он выглядит так:Код:int CvPlot::calculatePotentialYield ...
Как видно из приведенных изменений, я отказался от разделения iNoBonusYield, iYield и iBonusYield. Дело в том, что в моем варианте все минеральные Yield представлены исключительно как бонусы. К примеру железная руда есть только в месторождениях. Ни на одной другой клетке, за исключением бонусной (где собственно расположено месторождение), железной руды нет вообще. Именно поэтому я не вижу смысла разделять iNoBonusYield, iYield и iBonusYield. Тем более, что с ними невозможно вводить минусы для опреденных юнитов, что собственно и было основной целью данной "правки".
Итак, CvGameCoreDLL.dll скомпилирован без ошибок, начинаем игру.
На карте находим месторождение железной руды. Оно именуется как "Iron", названия я пока не правил. Запас железной руды в данном месторождении равен 20. Я специально уменьшил его на порядок, чтобы не добывать руду в течение сотни с лишним ходов.
Основывам рядом с месторождением город и селим в нем колониста (UNIT_COLONIST) и шахтера (UNIT_MINER). Для колониста в CIV4UnitInfos.xml прописаны ограничения:
То есть колонист может добывать руды или собирать табака на 2 единицы меньше. чем обычный юнит. Ниже будет дано пояснение для чего это сделано.Код:<YieldChanges> <YieldChange> <YieldType>YIELD_ORE</YieldType> <iChange>-2</iChange> </YieldChange> <YieldChange> <YieldType>YIELD_TOBACCO</YieldType> <iChange>-2</iChange> </YieldChange> </YieldChanges>
Для железной руды в CIV4BonusInfos.xml прописано:
Для табака (обычный ресурс, взят в качестве примера) в CIV4BonusInfos.xml прописано:Код:<YieldChanges> <YieldIntegerPair> <YieldType>YIELD_ORE</YieldType> <iValue>1</iValue> </YieldIntegerPair> </YieldChanges>
То есть при данном раскладе по логике должно быть так:Код:<YieldChanges> <YieldIntegerPair> <YieldType>YIELD_TOBACCO</YieldType> <iValue>3</iValue> </YieldIntegerPair> </YieldChanges>
UNIT_COLONIST:
Железная руда
+1 (с бонусной клетки) -2 (штраф на добычу руды) = -1 (то есть добыча руды невозможна)Теперь посмотрим какие профессии доступны колонисту.Табак:
+3 (с бонусной клетки) -2 (штраф на сбор табака) = +1 (то есть сбор табака возможен)
Как видно из приведенного выше снимка колониста невозможно поставить на добычу железной руды. Однако он может собирать табак в количестве 1 единицы. То есть мы имеем как раз тот вариант, что только что рассчитали.
Теперь посмотрим на возможности у второго юнита. Это шахтер (UNIT_MINER). Для него я ничего не правил и он может (как это и было в оригинале) добывать руду в 2 раза более эффективно. Он может также собирать табак, но уже как обычный юнит.
Приведенные на снимке цифры это прекрасно иллюстрируют. Железной руды он добывает в 2 раза больше, чем обычный юнит, то есть 2 единицы, а табака 3 единицы, то есть ровно столько, сколько прописано в CIV4BonusInfos.xml.
Идем дальше и строим шахту.
Опять-таки для ускорения ставим на бонусную клетку ораву строителей и они моментально сооружают шахту.
Шахта готова и сейчас на ней можно добывать 3 единицы железной руды.
Повторно проводим аналогичный расчет для колониста.
UNIT_COLONIST:
Железная руда:
+3 (с бонусной клетки + шахты) -2 (штраф на добычу руды) = 1 (то есть добыча возможна)
Действительно, на построенной шахте колонист может добывать руду, но всего лишь 1 единицу. Для сравнения профессиональный шахтер на этой же шахте может добывать 6 единиц руды:
или то же самое в городе:
Итак, сейчас можно ставить колониста на добычу руды, но труд его будет крайне неэффективным. Из этого следует, что для работы на шахте нужен профессиональный шахтер. Любой другой юнит там будет практически бесполезен. Аналогичные минусы я введу и по другим юнитам. Колонист в данном случае взят в качестве примера.
Шахтера можно купить в Европе или обучить колониста работе шахтера. Пока это возможно только в школе-колледже-университете, который нужно построить в городе. Однако я планирую добавить возможность обучения колониста профессии шахтера при его работе на шахте. У Kailric'a помнится был прекрасный мод, где такой способ получениея профессии был реализован. Причем обучение было разделено на два этапа, когда сначала неумеха-колонист превращался в подмастье (только 50% от максимальной производительности), а лишь в конце обучения становился профессиональным мастером (100% производительность). Тот маленький плюсик (+1) при добыче руды колонистом как раз и оставлен мной для реализации этой идеи.
Итак, продолжим добывать железную руду. Довольно скоро месторождение почти иссякнет. За один ход до этого мы имеем:
или то же самое в городе:
Как мы видели выше, профессиональный шахтер может добывать железной руды больше (+6), но месторождение содержит только 2 единицы руды, поэтому на следующий ход он сможет добыть только 2 единицы.
Этот точный расчет был еще одной из особенностей мода по исчерпаемым ресурсам, который я никак не мог загубить своими "правками".
На следующий ход бонусная клетка опустела
А в городском складе прибавилось ровно столько железной руды, сколько ее было в месторождении, то есть 20 единиц.
На первый взгляд все работает, как и планировалось, но нужно еще разок проверить.....
Привет, NeseryozniyVET!
Мы с тобой практически одновременно тут появились. В приведенном выше сообщении я как раз этот вариант и реализовал. Внесенные изменения в исходный код я впечатаю в сообщание вечером, а то в этом броузоре какие-то кракозябры вместо букв лезут.
Добавил в предыдущее сообщение скорректированный участок в исходных кодах.
Несколько снимков из рабочей версии мода, включающего в себя как минимум 4 части:
- "Новые колонисты", где рождение новых колонистов больше не связано с запасами еды на городском складе,
- "1492: Золотая лихорадка", где введены исчерпаемые минеральные ресурсы (в том числе россыпное золото),
- "1492: Закон и порядок" ("1492: Codex") - где разделены функции губернатора, представляющего в городе своего короля и обеспечивающего в нем порядок и рост производства, и "мятежного жителя", сеющего анархию и создающего предреволюционную ситуацию.
- "Радиус города на 2 клетки", где, как ясно из названия, доступная для обработки территория вокруг города увеличена с 8 до 20 клеток.
Плюс еще несколько мелких добавлений.
Обычный CvGameCoreDLL.dll работает без сбоев, но я все же дополнительно скомпилировал debug CvGameCoreDLL.dll и начал проверку рабочей версии на наличие ошибок с помощью этого самого debug CvGameCoreDLL.dll. Несколько багов поймать не только удалось, но и, выяснив причину, устранить. Как несложно догадаться все они были "рукотворными" и связаны с некритичными ошибками в xml файлах. Насколько это нужно было делать - сказать трудно, поскольку обычный CvGameCoreDLL.dll их не видит, но то, что теперь этих ошибок нет, явно пойдет на пользу стабильности мода.
Кроме того в результате теста удалось заметить и устранить несколько графических багов на экране. Они были связаны с неправильным изображением иконок "молотка" и "рождаемости". Если так называемый "hammer bug" хорошо известен тем, кто увеличивает количество yields в игре, то с иконкой рождаемости пришлось изрядно повозиться. По логике она должна была работать без проблем. Я несколько раз пропахал все дорожку, начиная от исходных кодов и заканчивая GameFont_75.tga, но безуспешно. Единственным объяснением на сей момент является то, что иконки,
совершенно правильно прописанные в CvEnums.h, превышают MAX_NUM_SYMBOLS, следы которого теряются в ехе файле игры.Код:BIRTHPOINT_CHAR, WAREHOUSE_CHAR,
Для решения проблемы пришлось дополнительно прописать появление иконки рождаемости в CvGameTextMgr.cpp
Только это полностью убрало графический баг с иконкой рождаемости.Код:szString.append(gDLL->getText("TXT_KEY_MISC_BIRTHPOINTS_INFO", pCity->getBirthPoints(), pCity->growthThreshold())); szString.append(gDLL->getSymbolID(BIRTHPOINT_CHAR));
В итоге информации о городе выглядит сейчас так:
Если заглянуть сейчас в город, то там можно также увидеть кое-что новое. Работающий губернатор повышает производительность труда всех работников. Если же в городе появляется "мятежный житель", то он будет понижать производительность труда. На данном снимке показан только первый вариант, поскольку в данном случае я проверял совсем другое. Если кого-то заинтересуют, то можете пройти посмотреть по ссылке на их-фанатики, гдя я выкладывал всю механику появления и работы "губернатора" и "мятежного жителя". Сейчас все это уже включено в данную версию и работает штатно.
Итак, перейдем к следующему этапу.
Обычная работающая шахта. Запас железной руды практически исчерпан.
На следующем ходу руда заканчивается. Обычно после этого шло автоматичесое разрушение уже пустой и соответственно бесполезной шахты. Напомню, теперь все минеральные ресурсы распределяются только в качестве бонусов. Если вся руда добыта, бонус удаляется с карты. Добывать на холме без бонуса что-либо (железную руду, серебро, и т.д.) невозможно. Их там попросту нет! Поэтому шахта без бонуса бесполезна. На следующем снимке это и происходит:
Одним из "мнимых" недостатков исчерпаемых ресурсов является то, что игрок что-то теряет. Когда на их-фанатиках я предлагал введение исчерпаемых ресурсов, мне прежде всего указывали на этот момент. Игрок видите ли понастроил инфрастуктуру для производства, к примеру, оружия (руда -> железо -> инструменты -> оружие), а тут, бац! и исходный материал для всей цепочки (железная руда) закончился. Все производство останавливается. Мол, такое не годится!
Но так ли это плохо? Ведь в реальности происходит именно так. Кроме того мы же заранее знаем сколько руды мы сможем добыть из данного месторождения, поэтому можем планировать объемы производства и скорости добычи. Более того, зная об ограниченности наших запасов руды, можем заранее начать поиск новых месторождений на пока закрытых участках карты. А найдя там новое месторождение, просто застолбить его, основав рядом свою колонию.
Но такие открытия месторождений возможны только на уже сгенерированной на первом ходу карте. Старателя (или говоря современным языком "геолога"), который мог бы открывать месторождения руд в ходе игры, пока нет.
Можно ли его ввести? Сложно сказать. Геология как поиск и открытие новых месторождений в ходе игры пока реализована только в моде "Эволюция войны" NeseryozniyVET. Но там, если мне не изменяет память, генерация очков геологии идет через город, а не через юнит, перемещающийся по карте и тем самым производящий геологоразведку. Впрочем, я могу ошибаться, так как смотрел как работает геология в "Эволюция войны" несколько месяцев назад.
Поэтому на данном этапе я начал поиск более простых и менее трудоемких способов открытия новых месторождений в ходе игры. Два из них я представляю в данном сообщении. Оба реализованы через генератор случайных событий.
Первый способ связан с уже опустевшей шахтой. Когда вся руда добыта, то на следующем ходу появляется такое сообщение:
Шахтеров понять можно. Что им делать в пустой шахте, где нечего добывать? Шахту можно разрушить, но "среди местных жителей ходит легенда о больших запасах руды где-то поблизости". Игроку я оставил только один выбор. "Ладно, пусть шахта пока стоит и разрушать ее не надо. Стоит проверить эту легенду". Так на карте вместо обычной работающей шахты появляется "depleted mine", которая ничего не производит и на которой никто не работает.
Насколько данная клетка нужна для иного производства? Пока вокруг города было 8 клеток, то вероятность этого была 1/8. Сейчас, когда вокруг города 20 свободных клеток, то это уже лишь 1/20. Таким образом, бесполезную пока шахту можно какое-то время не трогать.
Тем более, что есть шанс (он уже работает, но я его пока не прописал в виде сообщений на экране), что на неработающей шатхе старатель или местные мальчишки))) смогут найти новую, неизвестную пока рудную жилу. Другими словами, здесь "depleted mine" используестся для открытия нового месторождения, что и показано на снимке:
После этого на клетку с вновь открытым бонусом можно послать работника, который снова построит действующую шахту. Возможно (?), имеет смысл сделать эту шахту иной по виду, более дорогой по стоимости и трудозатратам на ее строительство, назвав к примеру "шахтой глубокого заложения".
Лежащие буквально на поверхности месторожения россыпного золота могут быть открыты иным способом. Наш скаут (я его авансом называю тут "старатель" или "prospector"), путешествуя по карте, имеет небольшой шанс найти необнаруженное пока месторождение россыпного золота. Выглядит это так:
Обнаружение россыпи
и ее появление на карте.
Все это происходит в процессе игры.
Я прекрасно понимаю, что это очень грубое приближении к реальной геологии, но пока есть и реально работает только оно.
MAX_NUM_SYMBOLS как и все остальные MAX_NUM_enums, вроде, используются только в DLL. Поэтому новые энумы нужно добавлять до MAX_NUM_enums. То есть, MAX_NUM_enums должен быть всегда в конце списка.
Если хочешь использовать новые иконки в текстовых файлах, то надо редактировать CvDllTranslator.cpp. Там изменения элементарные - сам догадаешся.
В моем моде все месторождения генерируются при создании карты, только они не видны. Чтоб увидеть месторождение надо чтоб на тайле накопились очки геологии. С помощью юнита накапливать очки геологии очень просто - начисляем их на тайл где стоит юнит. У меня очки геологии генерирует город и начисляет их на тайл с самым маленьким количеством этих очков. Все эти большие и сложные алгоритмы сделаны для максимально быстрого нахождения этого тайла.
Если новые технологии позволяют обходится без услуг простых людей - это прогресс, а если новые технологии позволяют обходится без услуг миллионеров и крупных компаний - это нарушение авторских прав.
Мой мод
Впечатления, конечно, непередаваемые, выглядит роскошно.
Но такой смешной вопрос: обновлялся ли первый пост с адресом мода, и лежит ли там его актуальная версия?
Я тут с таким огромным удовольствием вспоминаю старенькую игрушечку, захотел, конечно, попробовать установить и здешнее счастье, и, откровенно говоря, смущает отсутствие каких-либо дат в первой записи здесь (обычно на форуме при редактировании внизу добавляет плашку с датой редактирования, а тут не вижу).
Собственно, лежит ли там последний билд, и где его взять, если его там нет?
Новые строки с
я прописал неподсредственно над строкой сКод:BIRTHPOINT_CHAR, WAREHOUSE_CHAR,
Про эти "грабли" я помню, так как частенько на них наступал, поэтому тут все было сделано правильно.Код:#ifdef _USRDLL MAX_NUM_SYMBOLS #endif
А MAX_NUM_SYMBOLS я нашел в ехе файле, когда открыл его в Notepad++. Информации конечно это дало немного, но внутри по крайней мере было упоминание о MAX_NUM_SYMBOLS. Собственно поэтому я и предположил о максимально возможном количестве символов.
Кроме того, на их-фанатиках упоминалось о максимальном количестве бонусов, которые можно добавить. Если память мне не изменяет, то называлась цифра в 72. Если специально не изголяться, то можно ввести только 72 бонуса. Умельцы правда в каком-то из модов смогли обойти и это ограничение.
Все верно, CvDLLTranslator.cpp и CvDLLTranslator.h довольно просты для понимания и редактирования. Но есть одно небольшое "но". Они отсутствуют среди исходных кодов Колонизации. Оба эти файла есть в CivIVBTS, но их нет в CivIVColonization.
Последняя версия Колонизации - это сильно кастрированаая Цивилизация 4 BTS. Как оказалось, CvDLLTranslator.cpp и CvDLLTranslator.h файла пали жертвой как раз этой операции, а их функцию разработчики перенесли в оставшиеся исходные коды. Перенесли судя по всему не совсем удачно, поскольку при введении малейших изменений система иконок начинает давать сбои. Одним из таких сбоев был "hammer bug", когда при увеличении количество yields в игре исчезал значок "молотка". Примерно то же самое случилось и с иконкой рождаемости.
Но в обоих случаях лекарство от этих граблей уже найдено. Сейчас и "молоток" и "рождаемость" отображаются правильно и поэтому пока наверное нет смысла возвращать CvDLLTranslator.cpp и CvDLLTranslator.h.
Большое спасибо за пояснение. Механику открытия месторождений в EoW я представлял довольно близко, но не совсем так, как ты описал. Твой вариант с открытием месторождений прекрасно подходит для Цивилизации, когда у тебя временной промежуток исчисляется тысячелетиями. В этом случае месторождения железа или алюминия, естественно не нужны дикарям, бегающим с палкой или камнем за мамонтом за 2 тысячелетия до нашей эры.
В Колонизации же временной интервал сжат до 3-4-х сотен лет. Поэтому все месторождения, сгенерированные на материке на первом ходу, должны быть сразу видны. Это необходимо игроку для выбора оптимального места расположения своих городов. Запас в месторождении я рассчитываю так, чтобы истощение наступало во второй половине игры. Таким образом, где-то к середине игры появляется необходимость открытия новых запасов руды.
После длительных поисков, массы экспериментов в Blender и NifScope мне удалось-таки сделать юнит "Старатель". В качестве "Старателя" мне нужен был "некий юнит + навъюченная лошадь". "Юнит на коне" мне не подходидил по целому ряду причин. Среди файлов Цивилизации 4 BTS удалось найти "великого торговца", где был именно "юнит + навьюченный верблюд", но верблюд как-то плохо смотрится в Сибири или в дебрях Амазонки. Поэтому поиск пришлось продолжать довольно долго. Плюс разбираться с нуля с анимацией юнитов, чем я вообще никогда не занимался. В общем, пока удалось собрать такого "Старателя". Обе части (человек и лошадь) двигаются синхронно, у лошади в качестве багажа - мешки, оружие, лопата и кирка.
Пока в NifScope он выглядит так
и в игре
"Старателя" я еще не прописал в файлах, но это по задумке должен быть очень дорогой юнит, который можно только купить в Европе. Этот юнит должен быть вооружен для защиты от диких зверей, туземцев или европейцев из других стран в состоянии войны. Он должен иметь запас инструментов для ведения изысканий. И наконец "Старатель" должен иметь лошадь, чтобы не тащить все это на своем горбу.
Именно "Старателю" будет поручена задача поиска месторождений. Как именно? Пока сказать трудно. Теоретически есть несколько вариантов решения этой проблемы.
1. Через систему случайных событий, как это было сделано для скаута. Но в отличие от скаута, который может найти только россыпные месторождения золота, серебра и драгоценных камней (пока не введены), старатель сможет открывать также и рудные месторождения.
Для этого старателю нужно дать команду на перемещение по карте. Такая команда в игре уже есть, ей соответствует кнопка "Explore". В принципе, перевод еxplore на русский дает как минимум два варианта. Это "исследование местности", но это и "поиск полезных ископаемых". Так что вводить новую кнопку типа "Prospect" вряд ли стоит. В данном варианте "Старатель" будет просто перемещаться по карте и на каждой клетке у него есть очень маленький шанс найти что-то полезное.
Или напротив жестко прописать, что первое месторождение он открывает, к примеру, на 10 ходу, второе на 50, третье на 100, и т.д. Мне кажется это тоже можно сделать через систему случайных событий.
Однако при выполнеии команды "Explore" есть пара неприятных моментов.
Во-первых, юнит, получивший эту команду, перемещается до тех пор, пока на карте еще есть неоткрытые клетки. Скаут, который открыл все сухопутные клетки на карте, просто останавливается. Отсюда следует, что "Старатель" тоже в какой-то момент остановится. Но, как я уже сказал выше, старатель - очень дорогой юнит и потребность в нем возникает к середине игры, а значит большинство клеток на карте к этому времени может быть уже открыто. То есть команда "Explore" работать у старателя уже не будет.
Если порыться в исходных кодах, то можно найти это ограничение на перемещения после открытия всех клеток. Мне кажется, что оно здесь:
CvTeamAI.cpp:
Если просто закрыть этот участок кода, то тогда абсолютно все юниты, получившие команду "Explore", будут двигаться вечно, что безусловно плохо. Поэтому я хочу попробовать такой вариант:Код:bool CvTeamAI::AI_isExploringNeeded(CvUnit* pUnit) const .... if (iUnrevealedLandPlots == 0) { return false; } .....
Здесь логика простая. Если юнит, выполняющий команду "Explore", наш старатель (UNIT_PROSPECTOR), то он продолжает исследования. Если это любой другой юнит - то дальнейшие исседования карты невозможны. Профессиональных программистов прошу не морщиться. Да, тут жестко прописан конкретный юнит, но мне так проще, пусть это категорически не принято среди профи. По крайней мере такой вариант я могу скомпиллировать без проблем.Код://KJ Prospector START //UNIT_PROSPECTOR must continue to explore territory even if all tiles are revealed (iUnrevealedLandPlots == 0). // original closed by KJ as test START /* if (iUnrevealedLandPlots == 0) { return false; } */ // original closed by KJ as test END if (iUnrevealedLandPlots == 0) { //here UNIT_PROSPECTOR must have number 30 in CIV4UnitInfos.xml. Calculation starts from 0. if (pUnit->getUnitType() == 30) //OK with compilation, must be tested ingame { return true; } else { return false; } } //KJ Prospector END
2. Второй возможный вариант поиска месторождений старателем через цепочку "Старатель" => "Лагерь старателя" => открытие месторождения. Но это опять таки будет работать через систему случайных событий, где пара "Старатель" + "Лагерь старателя" с некой вероятностью открывают месторождения. Это более логичное решение, поскольку на поиск месторождения должно тратиться время в 4-6 ходов, пока лагерь есть на карте. Этот вариант - пока лишь на уровне идеи, поскольку в принципе ясно как сделать лагерь за 1 ход, но как из лагеря сделать снова старателя с лошадью через 4-6 ходов, пока не совсем понятно.
3. И наконец третий вариант открытия месторождений - через "MISSION_PROSPECT" (от слова "prospect" - проводить разведку, искать полезные ископаемые). Это наиболее сложный вариант, поскольку в нем нужно прописывать не только миссию (что несложно), но и в CvUnit.cpp писать новые разделы CvUnit::canProspect... и bool CvUnit:: prospect..., что находится далеко за пределами моих возможностей. Однако и тут открытие месторождения должно быть случайным, то есть фактически таким же как и для случайных событий, описанных в вариантах 1 и 2.
В общем, необходимо подумать, как лучше решить вопрос с открытием месторождений....
Необходимо дать небольше пояснение. Мод "1492: Глобальная Колонизация", обсужение которого ведется в этой теме, представляет собой компилляцию массы маленьких MODCOMP (под-модов). Каждый из таких MODCOMPов достаточно прост и касается лишь одного из новшеств. Это делается специально для выявления и устранения возможных багов, связанных в введением именно данного новшества.
В первом посту этой темы есть (или наверное точнее была) ссылка на одну из составляющих мода "1492: Глобальная Колонизация", а именно на "1492: Global Colonization. Resource Pack". Как следует из данного там описания в "Resource Pack" введены новые товары, новые професии и т.д. Тестирование показало ошибки и недоработки, за что особое спасибо всем попробовавшим и написавшим в этой теме. В конечной версии мода все они будут исправлены.
Но "1492: Global Colonization. Resource Pack" - это только маленькая часть того, что должно быть включено.
Уже сейчас можно наверняка сказать, что точно будет включено:
- масса новых ресурсов, профессий, зданий, улучшений,
- исчерпаемые минеральные ресурсы,
- восполнимые животные и растительные ресурсы,
- рост население города в Новом Свете через параметр рождаемости в нем, а не через избыток еды.
- погодные условия на суше и море.
И многое-многое другое, в том числе работорговля, пиратство, игра на глобальной карте Земли и т.д., что еще предстоит доработать прежде, чем вносить в финальную сборку.
Снимки, приведенные в моем последнем сообщении на этой странице, сделаны из мода, где включены как минимум 4 MODCOMPа ("Новые колонисты", "1492: Золотая лихорадка", "1492: Закон и порядок", "Радиус города на 2 клетки"). Эту сборку я тестирую и пока не выявил критических сбоев.
В конечном виде мод "1492: Глобальная Колонизация" пока отсутствует и поэтому нигде не публиковался. Однако все составные части будущего мода доступны и любой желающий может уже сейчас собрать из них свой вариант игры.