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

Тема: "1492: Global Colonization. Глобальная Колонизация"

Комбинированный просмотр

  1. #1
    Цитата Сообщение от NeserVET Посмотреть сообщение
    Решение проблемы я ему отправил личным сообщением несколько дней назад. Но, видимо, он опять в командировке.
    Нет, напротив ко мне гости приехали и мы неделю из-за стола не поднимались. А в командировку я уеду на несколько дней в самом конце этой недели.

    Итак, что получилось в последнем варианте, когда вводится

    Код:
     if (!GET_PLAYER(getOwnerINLINE()).isYieldEuropeTradable(eYield))// непродоваемые в европе
    Компиляция и запуск игры - без проблем.
    Набор городом "очков рождаемости" и поддержание "неприкосновенного запаса" еды в переполненном городском складе тоже все работает правильно.

    Затем идет та же самая ошибка.

    Вот город на 2 жителя. Скорость нормальная, вместимость склада 100, "неприкосновенный запас" еды равен 48. Остальное при переполнении должно удаляться.

    И тут снова, как и раньше удаление излишков идет строго слева направо, причем совершенно независимо от стоимость удаляемого товара. Я даже оставил на складе 100 единиц серебра, то есть товара следующего по списку после древесины (если идти слева направо).



    На следующий ход серебро было удалено, несмотря на то, что его цена была 19 монет и оно было самым дорогим товаром на переполненном складе.



    Так же были удалены излишки хлопка (3 монеты) и шкур (5 монет). Самая крайняя справа и при этом дешевая же железная руда (3 монеты) осталась нетронутой.

    Вот сообщения с экранаю Они не влезли в один снимок, поэтому я сделал три снимка по каждой позиции.
    Сначала исчезло серебро:



    Затем хлопок



    И наконец самыми последними были удалены шкуры:

    продвинь это сообщение в соцсеть:  

  2. #2
    Ну теперь причина ясна: цены на все товары почему-то не высчитываются и равны нулю.
    Прийдется искать причину.
    продвинь это сообщение в соцсеть:  

  3. #3
    Цитата Сообщение от NeserVET Посмотреть сообщение
    цены на все товары почему-то не высчитываются и равны нулю.
    Именно так! Цены на все товары оказываются равными нулю и поэтому понятна логика программы, когда она удаляет ресурсы по порядку слева направо. Ведь при нулевой стоимости без разницы что удалять - серебро или древесину.
    продвинь это сообщение в соцсеть:  

  4. #4
    Будем выяснять почему нерправильно высчитываются цены на ресурсы.
    Вставь
    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
    продвинь это сообщение в соцсеть:  

  5. #5
    Цитата Сообщение от NeserVET Посмотреть сообщение
    Будем выяснять почему нерправильно высчитываются цены на ресурсы.
    Вставь
    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
    Готово. Вот снимок после 1 хода



    Далее картинка не меняется. Цена везде остается нулевой, процент тоже нулевой, значения профит тоже не меняются....
    продвинь это сообщение в соцсеть:  

  6. #6
    Все понятно - формулу не правилно написал.
    надо чтоб было
    aiPrices[iYield] = (100 + getOverflowYieldSellPercent()) * GET_PLAYER(getOwnerINLINE()).getSellToEuropeProfit(eYield, 10);// Цена за 1000 единиц ресурса
    а сейчас используется такая
    aiPrices[iYield] = getOverflowYieldSellPercent() * GET_PLAYER(getOwnerINLINE()).getSellToEuropeProfit(eYield, 1000);// Цена за 1000 единиц ресурса
    продвинь это сообщение в соцсеть:  

  7. #7
    Только что дошло!! Выражение (100 + getOverflowYieldSellPercent()) одинаковое для всех ресурсов, поэтому его можно убрать и использовать такую формулу

    aiPrices[iYield] = GET_PLAYER(getOwnerINLINE()).getSellToEuropeProfit(eYield, 1000);// Цена за 1000 единиц ресурса
    продвинь это сообщение в соцсеть:  

  8. #8
    Компилирую.....

    Готовою. Ход 1:



    Цены (за 1000 единиц товара) соответствуют минимальным в Европе по всем позициям!

    Продолжаю тест, но он идет достаточно медленно из-за кучи сообщений после каждого хода.

    ЗЫ. Я тестирую вариант

    Код:
    					aiPrices[iYield] = (100 + getOverflowYieldSellPercent()) * GET_PLAYER(getOwnerINLINE()).getSellToEuropeProfit(eYield, 10);// Цена за 1000 единиц ресурса
    продвинь это сообщение в соцсеть:  
    Последний раз редактировалось kabjans; 10.09.2012 в 23:40.

  9. #9
    Я чуствую его приближение! (глобального мода)
    Автору дерзай и не останавливайся.
    продвинь это сообщение в соцсеть:  

  10. #10
    В процессе тестирования выявил и исправил пару небольших багов, а также сделал некоторые корректировки параметров.

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

    Это происходило из-за того, что в CvCity.cpp на момент перехода расчет велся так:
    Код:
    setBirthPoints(iGrowthThreshold - iBirthPoints);
    а должно было быть так:
    Код:
    setBirthPoints(iBirthPoints - iGrowthThreshold);
    В таком виде все работает правильно.

    2. Второй баг, уже в CvMainInterface.py, я создал сам, когда убрал в подсказку количество товаров на складе и его максимальную вместимость и оставил на экране только прирост наполняемости склада за ход (iProdusedYield).

    Все работало нормально до того момента, пока значения были iProdusedYield > 0 или iProdusedYield < 0. Но в ситуации, когда iProdusedYield = 0, значок склада с экрана просто исчезал. Для исправления этого я добавил в CvMainInterface.py строку с "else"
    Код:
    					if iProdusedYield > 0:		
    						szBuffer += u"+" + u"%i%c" % (iProdusedYield, CyGame().getSymbolID(FontSymbols.BAD_GOLD_CHAR)) + u"</font>"		
    						
    					elif iProdusedYield < 0:
    						szBuffer += u"%i%c" % (iProdusedYield, CyGame().getSymbolID(FontSymbols.BAD_GOLD_CHAR)) + u"</font>"
    	
    					else:					
    						szBuffer += u"%i%c" % (iProdusedYield, CyGame().getSymbolID(FontSymbols.BAD_GOLD_CHAR)) + u"</font>"	#KJ addon if "iProdusedYield = 0"
    Так все работает правильно.

    "BAD_GOLD_CHAR" пусть не смущает, так как в GameFont.tga значок склада я поместил вместо значка BAD_GOLD_CHAR, который в игре нигде не используется.

    3. Удлинил до 10 ходов предупреждение о скором переполнении городского склада. Теперь в CvMainInterface.py это выглядит так:
    Код:
    					elif iTotalYield + (10 * iProdusedYield) > iMaxYield:	#"10 turns's alarm before Max Storage capacity"				
    						szBuffer += u"255,255,0"			#yellow
    Как и было сделано VET'ом в оригинале, цифры перед значком склада меняют цвет с зеленого на желтый, но желтыми они становятся за 10, а не за 2 хода до возможного переполнения склада. Из-за обилия информации я частенько упускал этот момент и склад оказывался набит до предела.

    Теперь несколько замечаний по вновь введенным параметрам.

    4. Неприкосновенный запас продовольствия, задаваемый через
    Код:
    		<DefineName>TURNS_FOR_FOOD</DefineName>
    		<iDefineIntVal>12</iDefineIntVal>
    При скорости игры 1 ход = 1 месяц мы имеем годовой запас продуктов питания. Очень разумно. Если память мне не изменяет, то в СССР был 90 дневный неприкосновенный запас продовольствия. Тут же годовой. Так что мы имеем вполне соизмеримые величины.

    5. Как показывает практика городской склад (BUILDING_WAREHOUSE) не является тем зданием, которое строится самым первым. Ни игрок, ни тем более AI, не начинают стоить склад сразу.

    Это означает, что при нормальной скорости игры на самом первом ходу в городе может храниться только 100 единиц товара. Честно сказать, я не знаю откуда идет эта цифра, ведь склада в городе на самом первом ходу пока нет, а BUILDING_TOWNHALL, который есть по дефолту, имеет
    Код:
    <iYieldStorage>0</iYieldStorage>
    Другие доступные по дефолту здания тоже. Возможно эта сотня где-то прописана в исходных кодах, но, признаюсь, я специально не искал. Это не важно, просто примем эту сотню как данность. Итак, на самом первом ходу в городе может храниться не более 100 единиц товара.

    А теперь представим ситуацию, когда город основан юнитом, имеющим профессию "Драгун" (PROFESSION_DRAGOON). Согласно CIV4ProfessionInfos.xml в экипировку этого юнита входят:
    Код:
    			<YieldEquipedNums>
    				<YieldEquipedNum>
    					<YieldType>YIELD_HORSES</YieldType>
    					<iYieldAmount>50</iYieldAmount>
    				</YieldEquipedNum>
    				<YieldEquipedNum>
    					<YieldType>YIELD_MUSKETS</YieldType>
    					<iYieldAmount>50</iYieldAmount>
    				</YieldEquipedNum>
    			</YieldEquipedNums>
    То есть уже в момент основания все доступные в городе 100 единиц будут сразу же заполнены. Любой товар, что будет производиться в городе или собираться на клетках вокруг него, моментально будет подпадать под возможные сокращения.

    Для исправления этой ситуациидля в BUILDING_WAREHOUSE я ввел
    Код:
    <iYieldStorage>100</iYieldStorage>
    Таким образом, сейчас при нормальной скорости получается суммарная вместимость города (без еще не построенного склада!) равна 100 + 100 = 200, то есть в 2 раза больше прежней. В этом случае даже при создании города драгуном не происходит моментального переполения еще не построенного "склада".

    Соответственно в сторону повышения скорректированы и значения для BUILDING_WAREHOUSE
    Код:
    <iYieldStorage>900</iYieldStorage>
    вместо
    Код:
    <iYieldStorage>100</iYieldStorage>
    и для расширенного склада (BUILDING_WAREHOUSE_EXPANSION), где сейчас
    Код:
    <iYieldStorage>1500</iYieldStorage>
    вместо
    Код:
    <iYieldStorage>200</iYieldStorage>
    Эти изменения абсолютно необходимы, так как сейчас заполненность склада считается как сумма всех товаров, что хранятся в городе, а не отдельно по каждой из позиций, как это было в оригинальной игре.

    6. Максимальное значение BirthPoints, при котором рождается новый колонист. В самом начале это значение было равно 200:
    Код:
    		<DefineName>BASE_BIRTH_POINTS_THRESHOLD</DefineName>
    		<iDefineIntVal>200</iDefineIntVal>
    Но насколько оно оптимально?

    Для ответа на этот вопрос надо совершить небольшой экскурс в историю и демографию.

    Как известно, рост населения в любом городе определяется четырьмя слагаемыми.

    - рождаемость,
    - смертность,
    - иммиграция (в город)
    - эмиграция (из города).

    Таким образом,

    Прирост населения = (Рождаемость - Смертность) + (Иммиграция - Эмиграция).
    В первых скобках - естественный прирост населения, во вторых - искусственный (или механический).

    В данном моде мы не разделяем по отдельности "Рождаемость" и "Смертность". Введенный параметер "BirthPoints" нужно рассматривать как естественный прирост населения, то есть как (Рождаемость - Смертность).

    Безусловно, оба эти значения можно развести и параллельно с "BirthPoints" ввести "DeathPoints". Но тогда в какой-то момент, когда набирается некое количество "DeathPoints", нужно убивать одного из жителей города. Причем в обязательном порядке! Это неприятно и вряд ли будет приемлемо играющими, так как сейчас все юниты практически бессмертны. По крайней мере до тех пор, пока не началась война с туземцами или соседями-европейцами.

    Поэтому "Смертность" проще ввести через генерацию случайных событий. К примеру, в густонаселенном городе (более 8 или 10 жителей) с вероятностью Х% вспыхивает эпидемия. Если в городе нет доступа к чистой воде (родник), или нет госпиталя, или лекарств, то тогда с очень высокой вероятностью один из жителей умирает. Если все вышеперечисленное есть, то город в период эпидемии ничего не производит и все заканчивается без потерь для игрока.

    Мне кажется, что такое решение намного проще, чем введение параметра DeathPoints. Вероятностное событие может произойти, а может и не произойти. Тут все зависит от самого игрока.

    Итак, мы имеем два компонента, ответственных за прирост населения города - естественный и искусственный.

    Если изучить динамику роста городов в Новом Свете в период колонизации, то станет совершенно очевидно, что в первые как минимум 100 лет преобладающим механизмом был "искусственный" рост населения за счет:

    - иммигрантов из Европы (в самом начале игры мы их постоянно возим из Европы),
    - рабов из Африки (в данном моде отсутствуют, но они уже есть в "1492: Slavery Market. The Orient. Port-Royal"),
    - захваченных или присоединившихся к европейцам местных аборигенов (в нашем случае, это UNIT_CONVERTED_NATIVE).

    Кстати, массовый завоз рабов из Африки как раз и был связан с отсутствием необходимой рабочей силы во вновь основанных городах и в особенности на плантациях Нового Света.

    То есть другими словами, параметр BASE_BIRTH_POINTS_THRESHOLD мы должны задать таким, чтобы в течение очень длительного периода времени население города не могло увеличиваться. Если оставить его равным 200, то новый житель в нем появится через 100 ходов. Считаем 1 ход = 1 месяц, получаем 100 месяцев или 100 : 12 = чуть больше 8 лет. Лично мне кажется, что это очень быстро.

    Безусловно, увеличив BASE_BIRTH_POINTS_THRESHOLD до 300 или даже 500, мы получим более приемлемые значения. По крайней мере более правильные с исторической точки зрения. Поэтому моя рекомендация - использовать параметр BASE_BIRTH_POINTS_THRESHOLD с очень большим значением. Впрочем, это дело вкуса каждого из игроков и любой вправе поменять его сам. Параметр BASE_BIRTH_POINTS_THRESHOLD выведен в GlobalDefinesAlt.xml и его очень просто отредактировать.

    Других изменений, за исключением незаконченного пока редактирования текстовых файлов, я не делал. Сейчас я правлю статьи с CONCEPT_FOOD, CONCEPT_NEW_STORAGE и CONCEPT_POPULATION_GROWTH.

    Если мне ничего не помешает, то к концу этой недели мод "BirthPoints_and_NewCapacity" будет готов для публикации и представления игрокам.

    Предлагаю его переименовать и назвать к примеру "New Colonists" ("Новые колонисты"). При этом в описании указать, что в данном моде изменена логика генерации новых поселенцев. Новый колонист (см. предлагаемый вариант названия мода) появляется не в результате накопления еды, а как следствия набора "очков рождаемости" всеми жителями данного города. Плюс естественно описать радикальные изменения, произведенные с городским складом.

    Если новое название приемлемо, то тогда заставка твоего мода может выглядеть например так:



    Да, и последнее. При довольно продолжительном тестовом прогоне я открыл карту и видел, что и как делают мои европейские оппоненты и местные аборигены. Сразу же хочу сказать, что их поведение меня порадовало. Никто из них тупо не гнался за увеличением запасов еды. Все были заняты сбором или производством чего-то своего, имея при этом гарантированный запас продовольствия, который обеспечивал постоянный набор "очков рождаемости". И самое главное, это происходило независимо от того, что они делали в городе или на клетках вокруг города. Города росли не быстро, первоначально их рост происходил за счет прибытия новых колонистов из Европы, затем же они стали сами источниками новых поселенцев, которые постепенно расселялись по карте. Лично мне такое поведение очень даже понравилось.
    продвинь это сообщение в соцсеть:  

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

Ваши права

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

free counters