Привет, kirgre!
Перевод на русский безусловно имеет смысл, но только переводить надо конечный вариант, когда все (или почти все) сделано и тексты-описания в дальнейшем радикально меняться не будут. Пока же все находится в стадии постоянных изменений, причем эти изменения касаются как текстов-описаний, так и различных деталей.
К примеру, несколькими сообщениями выше я показал, как на заброшенной шахте можно заново открыть запасы руды. На тот момент это было единственное решение для "Квеста с заброшенной шахтой". Но сейчас, когда появился юнит "Старатель" решений для этого квеста будет как минимим три:
1. Заброшенная шахта не нужна, на этом месте будет построено другое улучшение (к примеру, посажена виноградная лоза, разведены овцы, и т.д.)
2. Заброшенная шахта должна быть обязательно сохранена. У меня (игрока) есть свободные деньги на немедленное приглашение (покупку) старателя. (Старатель тут же появляется в городе или на заброшенной шахте).
3. Заброшенная шахта должна быть обязательно сохранена, но у меня (игрока) в данной момент нет денег на немедленное приглашение (покупку) старателя. Я сделаю это при первой же возможности.
И это только один пример. Поэтому заниматься переводом сейчас - пустая трата времени.
Пока же все новые описания я собираю в отдельные xml файлы, так что объем перевода не будет слишком большим, а нововведения не надо будет вылавливать по крупицам в море уже переведенного русским издателем игры.
П.Ы. У меня нет русского варианта игры, поэтому мне сложно судить что там есть....
У меня версия от 1С лицензионка. Там, насколько я слышал, перевод технически отличается от того, что сделан наш-фанатиками тут, на форуме (порядок тегов языков в хмл разный). Так что, по-хорошему надо будет делать перевод и на пиратку, и на 1С лицензию отдельно.
ЗЫ: Да, кстати, насколько сложно сделать будет дерево технологий?
Мне сложно судить о качестве переводов, выполненных 1С или наш-фанатиками, поскольку я всегда пользуюсь оригинальным языком игры. Это, с одной стороны, позволяет избежать недоразумений, связанных с качеством перевода, а с другой, дает возможность вспомнить языки, которые когда-то довелось изучать.
Как делать дерево технологии в принципе понятно. У Kailric'a есть соответствующий мод на их-фанатиках. Вопрос в том, что конкретно туда надо включать и какие фишки за это игрок может получать. В принципе, я не исключаю, что небольшое технологическое древо будет сделано для мода "1492: ГК". По крайней мере несколько технологий, связанных с местными обычаями, культивированием местных культур, охотой и т.д. были бы весьма к месту.
Идея у меня вот какая: Сделать невозможным строительство зданий высших уровней (начиная от "фабрики") без знания станков и парового привода. Будет интересней и реалистичней, не?
Тогда и вашу идею с глубокой шахтой можно реализовать. Для строительства простой шахты ничего не надо, а для строительства улучшенной - паровой двигатель для осушения её.
Профессию можно обозвать изобретателем, работать может в школе/колледже/университете. Ну или отдельную лабораторию строить, хотя лаборатория в 1500 году будет выглядеть странновато. Можно сделать проще, хотя тоже не очень реально - Все ремесленные спецы и ученики генерируют немного "очков новаторства", для открытия технологии, допустим, "научный метод" к 1650 году, когда можно будет строить лабораторию.
В процессе тестирования нашел небольшую неувязку в скоростях роста народонаселения для различных наций.
В CvPlayer.cpp есть такой участок кода:
Меня собственно интересует первая часть этого участка, а именно:Код:int CvPlayer::getGrowthThreshold(int iPopulation) const { int iThreshold; //VET BirthPoints - begin 1/1 int iBASE_BIRTH_POINTS_THRESHOLD = GC.getBASE_BIRTH_POINTS_THRESHOLD(); if (iBASE_BIRTH_POINTS_THRESHOLD != 0) { iThreshold = iBASE_BIRTH_POINTS_THRESHOLD; } else { iThreshold = GC.getDefineINT("BASE_CITY_GROWTH_THRESHOLD"); } iThreshold += (iPopulation * GC.getDefineINT("CITY_GROWTH_MULTIPLIER")); //VET BirthPoints - end 1/1
Этот участок означает, что если рост города происходит за счет очков рождаемости (то есть если iBASE_BIRTH_POINTS_THRESHOLD != 0), то новый житель появляется когда iThreshold = iBASE_BIRTH_POINTS_THRESHOLD. Все просто и понятно.Код:if (iBASE_BIRTH_POINTS_THRESHOLD != 0) { iThreshold = iBASE_BIRTH_POINTS_THRESHOLD; }
Но именно здесь и кроется небольшой подвох.
Как известно сейчас рост населения города происходит по двум причинам.
1. за счет рождаемости внутри города (набор очков рождаемости). Эта величина, как следует из приведенного выше участка кода постоянна для всех наций.
2. за счет прибытия иммигрантов из Европы. Но иммиграция зависит от скорости набора крестов, а последняя величина разная у различных наций. Она самая высокая у англичан, остальные нации набирают кресты медленнее. Отсюда вытекает неравномерность развития. Таким образом, при игре за Англию игрок получает примерно 25% преимущество по скорости роста населения.
Эту неравномерность достаточно просто убрать, если слегка подкорректировать приведенный выше участок кода.
В выражении для всех наций за исключением АнглииКод:int CvPlayer::getGrowthThreshold(int iPopulation) const { int iThreshold; //VET BirthPoints - begin 1/1 int iBASE_BIRTH_POINTS_THRESHOLD = GC.getBASE_BIRTH_POINTS_THRESHOLD(); if (iBASE_BIRTH_POINTS_THRESHOLD != 0) { if //здесь ввести дополнее условие: //если игрок - Франция, Испания или Голландия //то { iThreshold = (iBASE_BIRTH_POINTS_THRESHOLD - 100); } else //в противном случае, то есть когда игрок - Англия { iThreshold = iBASE_BIRTH_POINTS_THRESHOLD; } } else {iThreshold = GC.getDefineINT("BASE_CITY_GROWTH_THRESHOLD");} iThreshold += (iPopulation * GC.getDefineINT("CITY_GROWTH_MULTIPLIER")); //VET BirthPoints - end 1/1
- 100 как раз и будет теми 25%, которые уровняют рост народонаселения для всех игроков, поскольку iBASE_BIRTH_POINTS_THRESHOLD = 400. При игре за все нации кроме Англии рождение нового поселенца произойдет быстрее на 25%.Код:iThreshold = (iBASE_BIRTH_POINTS_THRESHOLD - 100);
Как грамотно и самое главное правильно прописать это условие
Я перепробовал массу вариантов, но безуспешно.Код://если игрок - Франция, Испания или Голландия
Вроде бы нашел нечто подходящее в исходных кодах. В очень "сыром виде" для Франции это выглядит так:
А вот снимок из игры:Код:for (int iPlayer = 0; iPlayer < MAX_PLAYERS; ++iPlayer) { CvPlayer& kLoopPlayer = GET_PLAYER((PlayerTypes)iPlayer); if (kLoopPlayer.getCivilizationType() == 1) { iThreshold = (iBASE_BIRTH_POINTS_THRESHOLD - 100); } }
Тут два города. Слева французский, у него Threshold = 900. Справа - английский, у которого Threshold = 1200.
Игра идет на скорости 3х, поэтому 300 х 3 = 900, а 400 х 3 = 1200.
В GlobalDefinesAlt.xml задано только одно значение
Дополнено:Код:<Define> <DefineName>BASE_BIRTH_POINTS_THRESHOLD</DefineName> <iDefineIntVal>400</iDefineIntVal> </Define>
Странно, но эту строку
игра принимает за данность и абсолютно все европейские цивилизации имеют Threshold = 900, кроме Англии, у которой, как и положено Threshold = 1200. Я думал, что для каждой нации надо прописывать свое условие.Код:if (kLoopPlayer.getCivilizationType() == 1)
В принципе, для конкретно данного приложения меня это вполне устраивает, но хотелось бы понять логику программы, поскольку есть идеи как этот же трюк применить в других случаях. ....
Еще вчера вечером, когда я писал эти строки, у меня было подозрение, что найденное решение неверно. Поэтому я и написал "вроде бы".
Кроме того меня смeщало и другое:
После проверки все встало на свои места.
Найденный вариант работает только если играть за Англию.
Причина тоже ясна. Перебор идет через номер игрока (Player), а не порядковый номер цивилизации из CIV4CivilizationInfos.xml, как я ранее думал. Если я начну за Францию или любую другую страну, то именно у меня будет самым высоким iThreshold. Все остальные нации получат 25% снижение для iThreshold. что неверно.
Увы, но найденное мной псевдо-"решение" не годится и вопрос остается открытым.
Как правильно прописать условие в данном примере:
Код:if //если игрок - Франция, Испания или Голландия //то { iThreshold = (iBASE_BIRTH_POINTS_THRESHOLD - 100); } else { iThreshold = iBASE_BIRTH_POINTS_THRESHOLD; }
Вопрос снимается.
Мне удалось найти предельно простое и элегантное решение. Теперь каждая нация, включая аборигенов, имеет свой собственный NationalPopulationCoefficient, который определяет величину Threshold, при достижении которого в городе данной нации рождается новый житель.
Вот снимок из игры:
Параметры:
- скорость нормальная,
- BASE_BIRTH_POINTS_THRESHOLD = 400
- NationalPopulationCoefficient:
-- для Англии 500
-- Франции 200
-- Испании 100
-- Голландии 300
-- для аборигенов из племени Arawak 40.
На снимке видим значения Threshold. Они равны 400 + NationalPopulationCoefficient. У каждой нации свое значение Threshold.
В данном примере все значения NationalPopulationCoefficient взяты с потолка. Это сделано для того, чтобы увидеть разницу. В конечном варианте они должны быть скорректированы с учетом демографических особенностей европейских переселенцев и местных аборигенов. К примеру, рождаемость в племени аборигенов Крайнего Севера, будет значительно ниже, чем у их более южных собратьев, живущих в краях, "где среди пампасов бегают бизоны"...
Вот это ты намудрил!!
Скорость набора крестов завистит от CvPlayer::immigrationThreshold(). А она в свою очередь зависит от GC.getTraitInfo(eTrait).getImmigrationThresholdModifier(). Так что надо было просто убрать TRAIT_TOLERANT из Assets\XML\Civilizations\CIV4TraitInfos.xml и все его упоминания в других файлах.
Если новые технологии позволяют обходится без услуг простых людей - это прогресс, а если новые технологии позволяют обходится без услуг миллионеров и крупных компаний - это нарушение авторских прав.
Мой мод
Ты абсолютно прав относительно параметра, влияющего на скорость набора крестов, а следовательно и на скорость иммиграции из Европы. Именно эти 25% и привлекли мое внимание при тестировании. Они прописаны в CIV4TraitInfos.xml в строке:
Если ставится задача уровнять скорости роста населения для всех наций, то простейшее решение - элементарно обнулить все значения iImmigrationThresholdModifier, заменив в этой строке -25 на 0:Код:<iImmigrationThresholdModifier>-25</iImmigrationThresholdModifier>
При этом отпадает необходимость убирать TRAIT_TOLERANT.Код:<iImmigrationThresholdModifier>0</iImmigrationThresholdModifier>
Но что мы получим в результате?
Как известно сейчас рост населения города происходит по двум причинам:
1. за счет рождаемости внутри города (набор очков рождаемости). Эта величина постоянна для всех наций.Рост населения города = за счет рождаемости внутри города + за счет прибытия иммигрантов из Европы
2. за счет прибытия иммигрантов из Европы. Обнулив iImmigrationThresholdModifier, мы уровняем и этот параметр для всех наций.
В итоге скорости роста населения у всех наций будут равны, поскольку равны скорости естественного прироста населения в городах Нового Света и равны скорости иммиграции из Европы.
Это простейшее из возможных решений. Но, увы, далеко не самое лучшее.
В игре разработчики нагородили массу глупостей и несуразностей. Но в вопросе иммиграции поселенцев из Европы они были совершенно правы, по крайней мере английских. Достаточно вспомнить религиозные распри в Англии, унесшие жизни почти четверти всего населения. Или опять-таки религиозные (так называемые гугенотские) войны между католиками и протестантами (гугенотами), которые раздирали Францию при последних королях династии Валуа (1562-1598). Именно данные события в этих странах и были основной движущей силой иммиграции их граждан в Новый Свет. Люди просто бежали из стран, где их убивали из-за их религиозных взглядов.
Собственно возможно поэтому в игре разработчики в качестве символа иммиграции и избрали значок креста. Учитывая сказанное выше, было бы исторически неправильным обнулять значения iImmigrationThresholdModifier для английских и французских королей, уравнивая скорость иимиграции из этих стран с Испанией и Португалией, которые те времена были сравнительно более моноконфессиональными государствами, а следовательно иммиграция их жителей в Новый Свет имела иную причину.
Отсюда следует, что iImmigrationThresholdModifier должны быть различными для различных наций. К примеру, -25 для Англии и Франции, и 0 для Испании и Португалии. Но как раз это и приводит к той неувязке в скоростях роста народонаселения для различных наций, с которой я начал обсуждение этой проблемы. Второе слагаемое различно для разных наций:
Полностью решить проблему прекрасно позволяет введение iNationalPopulationCoefficient. Каждая их наций в игре - не только европейские поселенцы, но и местные аборигены - имеют свой собственный предел iThreshold, при достижении которого в городе данной нации рождается новый житель. Здесь мы корректируем первое слагаемое:Рост населения города = за счет рождаемости внутри города + за счет прибытия иммигрантов из Европы
В итоге сейчас мы можем подобрать такие комбинации для iImmigrationThresholdModifier и iNationalPopulationCoefficient, при которых ни одна из европейских наций не получит бонусов в росте населения.Рост населения города = за счет рождаемости внутри города + за счет прибытия иммигрантов из Европы
Одновременно, iNationalPopulationCoefficient позволяет корректировать скорость роста наций местных аборигенов. Причем для каждой нации iNationalPopulationCoefficient может быть своим. Выше я уже приводил пример, когда поселения народностей Крайнего Севера растут медленне, чем у их более южных собратьев. Причина - более суровый климат на севере. Одновременно поселения всех без исключения местных аборигенов должны расти несколько быстрее, чем города европейцев в Новом Свете. Причина также очевидна: аборигены живут в данной местности веками, прекрасно адаптировались к местным условиям, имеют иммунитет против местных болезней и т.д. У только что прибывших европейцев ничего этого нет.
Значения <iNationalPopulationCoefficient> выведены в CIV4CivilizationInfos.xml, поэтому их легко править, если при тестировании что-то пойдет не так.
Мне кажется, такое решение намного более правильным по целому ряду причин.
Kabjans, решение с населением технически и логически верно, но так ведь у Англии в оригинальной игре таким образом (за счёт +25% к эмиграции) и появлялось преимущество в населении... По крайней мере, на начальных этапах игры, когда колонистов в Европе массово не купишь. В твоём варианте получается, что преимущество Англии скомпенсировано в 0. Таки в чём цимес?
У тех стран, к примеру той же Англии, преимущество в более быстром росте населения на начальном этапе как было, так и останется. Ведь +25% к эмиграции в Новый Свет предложенный мной вариант никак не отменяет. Однако это преимущество верно только для начального этапа игры.
Проблема в неравномерности роста населения возникает при длительной игре, поскольку эти "+25% к эмиграции" работают на протяжении всей игры. И вот именно здесь - на продвинутых этапах игры - и требуется небольшая компенсация для наций, у которых нет плюса к эмиграции. Именно эту функцию и выполняет NationalPopulationCoefficient.
Значения <iNationalPopulationCoefficient> выведены в CIV4CivilizationInfos.xml, поэтому их любой сможет поправить по своему желанию. Лезть для этого в исходные коды игры и компилировать заново CvGameCoreDLL.dll не потребуется. Достаточно уметь пользоваться Блокнотом (Notepad).
Большое спасибо и естественно взаимно!
Очень кратко о том что сделано за последний месяц:
1. кардинально переработана иммиграция в Новый Свет.
Теперь туда едут в основном простые поселенцы, бывшие каторжники и уголовники. Редко среди них будут попадаться обладатели "полевых" профессий - фермеры, лесорубы, рыбаки и т.д. Еще реже - специалисты с "городскими" профессиями - кузнецы, строители и т.д. Практически никогда - высшее сословие: администраторы и служители культа.
Для последних предполагается использовать особый режим генерации, типа того, как это было сделано в моде "1492: Codex", когда при основании второго города король сам посылает администратора для управления своими колониями.
Аналогично будет сделано и для служителей культа, когда церковное руководство будет посылать священников в Новый Свет, которые будут проводить службы в церквях или миссионеров для "обращения туземцев в веру Христову".
С солдатами, по-видимому, тоже следует поступать аналогичным образом.
Если следовать логике мода "1492: Глобальная колонизация", то европейский король - единственный и полноправный хозяин колоний в Новом Свете. Он заинтересован в порядке (администратор) и безопасности своих владений (солдат), церковь же - в следовании поселенцев вере Христовой (священник).
Каждый игрок в праве следовать этим правилам или напротив выступать против них, генеря "колокола свободы" и в итоге провозглашая независимость.
2. новая система обучения.
Отказ от свободного и неограниченного притока специалистов из Европы потребовал введения корректив в систему обучения в Новом Свете. Сейчас обучение возможно по трем типам:
Тип 1: обучение колонистов среди туземцев. Эту часть я пока не трогал, она осталась практически без изменений.
Тип 2: обучение в процессе работы.
Это совершенно новый тип обучения и его я перенес из немецкого мода "ТАС 2.03", внеся ряд существенных дополнений и изменений.
Логика в данном случае предельно простая. Колонист, прибывший из Европы и не имеющий никакой професии, начинает работать к примеру дровосеком. Если он занят без перерыва на этой работе, к примеру, 10 месяцев (1 ход = 1 месяц), то у него есть шанс стать профессиональным лесорубом либо сразу после непрерывного 10-месячного махания топором, либо с задержкой на 1-3 месяца. (ЗЫ, мне тоже приходилось валить лес, но нас - молодых тогда еще ребят - обучили этому делу максимум за час. Так что 10 месяцев это ооочень много, если сравнивать с реальной жизнью.)
Если же колонист через несколько ходов занялся другой работой, стал к примеру строителем, то его счетчик обнуляется и расчет идет по новой. Если колонист меняет профессии как перчатки, то он никогда не научится никакой профессии. Если кто помнит, то таких в советское время величали "летунами".
"Стаж непрерывной работы на данном месте" (извиняюсь за бюрократический сленг) для разных профессий различен. Он минимален для традиционных в Европе "полевых" профессиий (рыбак, лесоруб, фермер), немного больше для неизвестных европейцам "полевых" профессий (разведения табака, выращивание какао и т.д.), еще больше для "городских профессий и максимально большой для профессий высшего уровня (администратор, священник).
Эта часть уже полностью реализована и работает коррестно.
3 Тип: обучение в школах, колледжах, университетах.
В данном разделе мне лишь частично удалось исправить ситуацию.
Прежде всего простейший вопрос: о каком собственно обучении идет речь?
Ответ: речь идет о профессиональном обучении, то есть колонист после обучени получает профессию.
Что мы имеем в оригинальной версии игры? Для примера я возьму марафонскую скорость. Обучение в школе - 60 циклов, в колледже - 45, в университете - 30.
НО!!!
Школа выпускают лишь специалистов самых простейших профессий - типа рыбаков, фермеров и т.д. Но учат их 60 циклов!
Университет же выпускает высшее сословие (администраторов, священников), но на это требуется всего 30 циклов!
Ясно же, что система обучения стоит на голове. Я изменил логику и сейчас она более соответствует действительности.
Обучение в школе самое короткое, но школа и дает лишь простейшие профессии, колледж - обучение длиннее, но и профессии после нее колонист получает более сложные, университет - самое длительное обучение, но зато там можно обучить самым сложным профессиям. В этом случае система обучения становится с головы на ноги.
Нечто подобное было в прошлом. Достаточно вспомнить систему профобучения в СССР: профучилище (рабочий), техникум (мастер), институт (инженер).
Сроки обучения в школах, клледжах, университетах легко согласовать с обучением на рабочем месте по типу 2.
Как вариант такое соотношение:
(первая цифра - простейшая "полевая" профессия, вторая цифра - городская профессия, третья цифра - наиболее сложная профессия)
Обучение на рабочем месте: 10 - 30 - 90
Обучение в учебном заведении: 15 - 30 - 45
Из цифр следует, что учиться полевым профессиям лучше работая, а не протирая штаны за партой.
Для городских профессий разницы нет, но необходимо наличия коллежда, а это время и деньги (стройматериалы)
Однако колледж необходим как ступень для строительства университета, поскольку высшие по сложности профессии лучше получать именно учась, а не работая на них.
Описанное выше также реализовано и работает корректно.
Здесь можно было бы поставить точку, но есть небольшой ньюанс, на котором я споткнулся. Он заключается в том, что колледж и университет выпускают всех специалистов одновременно. К примеру ниверситет через 45 циклов может выпустить как простейшего дровосека, так и администратора. Если первый будет бесплатным, то за последнего придется дополнительно выложить некое количество монет.
Но учатся-то они одинакое по продолжительности время! А, если по уму, то должны разное.
Дровосек в университете или коллежде должен заканчивать обучение через столько же циклов, как и в школе. Если в школе у него на обучение уходит 15 циклов, то в колледже или университете у него должна быть возможность закончить обучение через те же самые 15 циклов, а не сидеть там в 2 или 3 раза дольше положенного.
Совершенно аналогично для кузнеца. Его можно обучить только в колледже или университете, в школе - нельзя. На обучение в колледже требуется 30 циклов + некая кучка монет. Так и в университете кузнеца мы должны получить через те же самые 30 циклов + кучка монет.
Вместо этого и дровосек, и кузнец (я взял их обоих исключительно в качестве примера) торчат в университете втрое или в коллежде вдвое дольше положенного. Я пытаюсь исправить это, но пока, увы, безуспешно...
Что имеем на данный момент?
В CvUnit.cpp решение об окончании обучения описывается так:
Берется educationThreshold() для данного города и сравнивается с накопленным количеством очков обучения getYieldStored(). Если их накоплено больше или столько же, как и необходимо, то процесс обучения заканчивается и колонист получает одну из доступных в данном городе специальностей.Код:if (pCity != NULL) { if (getYieldStored() >= pCity->educationThreshold()) { if (isHuman()) { CvPopupInfo* pPopupInfo = new CvPopupInfo(BUTTONPOPUP_CHOOSE_EDUCATION, pCity->getID(), getID()); gDLL->getInterfaceIFace()->addPopup(pPopupInfo, getOwnerINLINE()); } else { pCity->AI_educateStudent(getID()); } } }
Если я не ошибаюсь, то выбор доступных специальностей идет через
Я пробил исходные коды на "BUTTONPOPUP_CHOOSE_EDUCATION". Возможны три места, где программа составляет список юнитов, находящихся в данном городе на момент окончания образования. ЭтоКод:CvPopupInfo* pPopupInfo = new CvPopupInfo(BUTTONPOPUP_CHOOSE_EDUCATION, pCity->getID(), getID());
1. CvDLLButtonPopup.cpp
2. тот же самый CvDLLButtonPopup.cpp:Код:case BUTTONPOPUP_CHOOSE_EDUCATION: if (pPopupReturn->getButtonClicked() == GC.getNumUnitInfos()) { CvCity* pCity = GET_PLAYER(GC.getGameINLINE().getActivePlayer()).getCity(info.getData1()); if (pCity != NULL) { gDLL->getInterfaceIFace()->selectCity(pCity, true); CvPopupInfo* pInfo = new CvPopupInfo(BUTTONPOPUP_CHOOSE_EDUCATION, info.getData1(), info.getData2()); gDLL->getInterfaceIFace()->addPopup(pInfo, GC.getGameINLINE().getActivePlayer(), false, true); } } else if (pPopupReturn->getButtonClicked() >= 0) { gDLL->sendDoTask(info.getData1(), TASK_EDUCATE, info.getData2(), pPopupReturn->getButtonClicked(), false, false, false, false); } break;
3. CvGameTextMgr.cpp:Код:case BUTTONPOPUP_CHOOSE_EDUCATION: { PlayerTypes ePlayer = GC.getGameINLINE().getActivePlayer(); CvCity* pCity = GET_PLAYER(ePlayer).getCity(info.getData1()); if (NULL == pCity || pCity->getOwnerINLINE() != ePlayer) { gDLL->getInterfaceIFace()->popupSetAsCancelled(pPopup); } else { gDLL->getInterfaceIFace()->lookAtCityOffset(pCity->getID()); } } break;
В принципе понятно, что именно программа делает. Она составляет список юнитов, находящихся в данном городе. Я подозреваю, что этот списоск есть Data2(). А когда приходит момент выбора специальности обучившимся студентом, то выдает этот список для выбора одной из профессий.Код:case BUTTONPOPUP_CHOOSE_EDUCATION: { CvPlayer& kPlayer = GET_PLAYER(GC.getGameINLINE().getActivePlayer()); CvCity* pCity = kPlayer.getCity(info.getData1()); CvUnit* pUnit = kPlayer.getUnit(info.getData2()); if (pCity != NULL && pUnit != NULL) { BuildingTypes eSchoolBuilding = pCity->getYieldBuilding(YIELD_EDUCATION); if (eSchoolBuilding != NO_BUILDING) { szString += gDLL->getText("TXT_KEY_MINIMIZED_CHOOSE_EDUCATION", pUnit->getNameOrProfessionKey(), pCity->getNameKey(), GC.getBuildingInfo(eSchoolBuilding).getTextKeyWide()); } } } break;
Мне до сих пор ни разу не приходилось встречаться с Data1() или Data2() "врЕменными матрицами" (вряд ли термин верный, поэтому прошу специалистов не бить сильно ногами). По-моему, именно в них зашита та информация, которую мне нужно выправить. Пока я ищу пути как это можно сделать. Если кто-то знает, как это сделать, то я буду очень признателен за совет. Заранее большое спасибо!
С наступающим Новым Годом всех, кто находит время заходить на форум и читать данную тему.
Есть! А что кого-то уже понесли?
Как шутят в Одессе
Группа людей со скорбными лицами и музыкальными инструментами. Впереди бригадир - дирижер. Звонок. Выходит жилец.
Бригадир (вежливо приподнимает шляпу): Ай-я-яй, мне уже говорили. Такое горе!
Жилец: Какое горе?
Бригадир: У вас похороны?
Жилец: Похороны?
Бригадир: Ришельевская шесть, квартира семь?
Жилец: Да.
Бригадир: Ну?
Жилец: Что?
Бригадир: Будем хоронить?
Жилец: Кого?
Бригадир: Что значит "кого"? Кто должен лучше знать, я или ты? Ну, не валяй дурака, выноси.
Жилец: Кого?
Бригадир: У меня люди. Оркестр. Пятнадцать человек живых людей. Они могут убить, зарезать любого, кто не вынесет сейчас же. Маня, прошу.
Толстая Маня, в носках и мужских ботинках, ударила в тарелки и посмотрела на часы.
Жилец: Минуточку, кто вас сюда прислал?
Бригадир: Откуда я знаю? Может быть, и ты. Что, я всех должен помнить?
Из коллектива вылетает разъяренный Тромбон.
Тромбон: Миша, тут будет что-нибудь, или мы разнесем эту халабуду вдребезги пополам. Я инвалид, вы же знаете.
Бригадир: Жора, не изводите себя. У людей большое горе, они хотят поторговаться. Назовите свою цену, поговорим как культурные люди. Вы же еще не слышали наше звучание.
Жилец: Я себе представляю.
Бригадир: Секундочку. Вы услышите наше звучание - вы снимете с себя последнюю рубаху. Эти люди чувствуют чужое горе, как свое собственное.
Жилец: Я прекрасно представляю.
Бригадир: Встаньте там и слушайте сюда. Тетя Маня, прошу сигнал на построение. Толстая Маня ударила в тарелки и посмотрела на часы.
Бригадир (прошелся кавалерийским шагом): Константин, застегнитесь, спрячьте свою нахальную татуировку с этими безграмотными выражениями. Вы все время пишете что-то новое. Если вы ее не выведете, я вас отстраню от работы. Федор Григорьевич, вы хоть и студент консерватории, возможно, вы даже культурнее нас - вы знаете ноты, но эта ковбойка вас унижает. У нас, слава Богу, есть работа - уличное движение растет. Мы только в июле проводили пятнадцать человек.
Теперь вы, Маня. Что вы там варите на обед, меня не интересует, но от вас каждый день пахнет жареной рыбой. Переходите на овощи или мы распрощаемся. Прошу печальный сигнал.
(Оркестр играет фантазию, в которой с трудом угадывается похоронный марш).
Жилец (аплодирует): Большое спасибо, достаточно. Но все это напрасно. Наверное, кто-то пошутил.
Бригадир: Может быть, но нас это не касается. Я пятнадцать человек снял с работы. Я не даю юноше закончить консерваторию. Мадам Зборовская бросила хозяйство на малолетнего бандита, чтоб он был здоров. Так вы хотите, чтоб я понимал шутки? Рассчитайтесь, потом посмеемся все вместе.
Из группы музыкантов вылетает разъяренный Тромбон.
Тромбон: Миша, что вы с ним цацкаетесь? Дадим по голове и отыграем свое, гори оно огнем!
Бригадир: Жора, не изводите себя. Вы же еще не отсидели за то дело, зачем вы опять нервничаете?
Жилец: Почем стоит похоронить?
Бригадир: С почестями?
Жилец: Да.
Бригадир: Не торопясь?
Жилец: Да.
Бригадир: По пятерке на лицо.
Жилец: А без покойника?
Бригадир: По трешке, хотя это унизительно.
Жилец: Хорошо, договорились. Играйте, только пойте:
в память Сигизмунд Лазаревича и сестру его из Кишинева.
(Музыканты по сигналу Мани начинают играть и петь:
"Безвременно, безвременно... На кого ты нас оставляешь? Ты туда, а мы - здесь. Мы здесь, а ты - туда". За кулисами крики, плач, кого-то понесли).
Бригадир (повеселел): Вот вам и покойничек!
Жилец: Нет, это мой сосед Сигизмунд Лазаревич. У него сегодня был день рождения.
Работа над модом продолжается. Я не пишу о каждом внесенном дополнении на форуме, поскольку, во-первых, это требует массы времени, а во-вторых, шаг или даже несколько шагов вперед, сделанные вчера, могут оказаться путем в тупик.
Вот один из примеров.
Дерево - единственный источник "молотков" в оригинальной игре и во всех модах, вышедших до сих пор. Это работает по схеме "Дерево" => "Плотник" => "Молоток".
Но почему? Ведь испокон веков как минимум два исходных материала использовались и до сих пор используются при строительстве - дерево и камень.
Камень как неисчерпаемый ресурс уже есть в моде "1492". Вполне естественно было сделать его вторым источником "молотков", тем более, что это достаточно просто. В результате появилась цепочка "Камень" => "Каменщик" => "Молоток", для которой были созданы юниты "каменотес" и "каменщик". Для последнего уже как профессионала-каменщика была создана оригинальная инфрастуктура в виде зданий, где "каменщик" будет работать, превращая "камень" => "молоток", то есть фактически строя здания в городе.
Все это построение было совершенно гармонично и правильно до тех пор, пока не была введена специализация городов. Что это значит? Практически все юниты могут заложить обычный город, что сейчас доступно в оригинальной игре. Но есть два типа юнитов, которые могут заложить город-форт (военные юниты) или город-монастырь (монахи). Причем форт и монастырь - это не улучшения в пределах уже существующего города, а именно полноценные города, развивающиеся по своим принципам с соответствующей инфраструктурой. К примеру в городе-монастере никогда не будет защитных сооружений или производства оружия. и т.д.
Однако при введенной специализации городов использование уже сделанных моделей развития
плюс"Дерево" => "Плотник" => "Молоток"
оказалось логически неверным. Возникали два вопроса "что строить" и "кто в построенном здании будет работать". Если игрок эти вопросы может решить без труда, то для тупого ИИ они могут оказаться неразрешимыми. Простого и понятного ответа на эти вопросы не было и схему пришлось переделывать."Камень" => "Каменщик" => "Молоток"
Для этого в мод "1492" понадобилось ввести и адаптировать пару дополнительных мини-модов, а именно "MultipleYieldsConsumed & MultipleYieldsProduced" и "Multiple Professions per Building". Плюс ввести нового юнита "строителя".
Лишь после этого удалось реализовать логически правильную конструкцию: юнит строитель может работать либо как профессиональный плотник (использует древесину при строительстве), либо как профессиональный каменщик (использует камень). Для строителя создана своя инфраструктура "WorkPlace" = "WorkShop" = "WorkHouse". Возникшая в прошлой схеме двойная глупость, когда каменшик работал в домике плотника и строил здания из дерево столь же эффективно, как и плотник - исчезла.
Это один из примеров работы над модом.
Сейчас в мод "1492" добавлен внутренний рынок, когда произведенные в городе товары в основном потребляются жителями данного города. Исторически это абсолютно правильно. В период колонизации никто в Европу не гонял галеоны, наполненные доверху промышленными товарами, изготовленными колонистами Нового Света. В Европу шло практичеки исключительно одно сырье: хлопок, шерсть, прочие необработанные материалы.
Действующая схема внутреннего рынка в принципе открывает возможность ввести и такие интересные фишки, как к примеру "изготовление" фальшивых денег из добываемого золота и серебра. Вспомните к примеру историю Невьянской башни, где по одной из легенд располагались тайные мастерские, в которых Демидовы чеканили фальшивые золотые и серебряные монеты.
Если ввести эту особенность достаточно рано (до 1536 года), то монеты должны быть фальшивыми, поскольку старейший монетный двор Америки, начал чеканку только в 1536 году. Кроме того стоимость монет можно сделать выше стоимости металлов (серебро, золото), используемых при их изготовлении.
Для логически правильного осуществления этой идеи требуются достаточно серьезные правки в исходных кодах или ... На данный момент я уже испробовал два совершенно различных варианта решения и при компиляции без единой ошибки (!!!), игра в обоих случаях падает на одном и том же месте. Почему - пока неясно. В общем, сейчас готового решения по данному вопросу у меня нет. Есть еще один перспективный вариант, но для его проверки мне надо добраться до компьютера с исходными кодами и модом...