Project cataclysm гайд по квестам

Обновлено: 02.07.2024

Photo 2020-01-11 12-16-52.jpg

В одном мире можно создать несколько персонажей, при этом сохраняются последствия действий каждого персонажа, все монстры и NPC. Можно наткнуться на собственный труп и пожитки. Но персонажи обычно стартуют довольно далеко друг от друга.

"Танки и другой транспорт" - добавляет брошенную военную технику и большой набор военных деталей.

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

Размер городов и расстояние [ ]

Размер города определяет количество зомби и лута, расстояние - площадь дорог и дикой природы.

При значении расстояния больше 7 игра может забыть сгенерировать города.

Сложность [ ]

Для упрощения игры можно увеличить множитель предметов до 1.5 (но лучше оставить 1), и снизить скорость монстров до 50%.

Обычно играют с множителем предметов < 0.5 и множителем монстров > 2.0.

Рекомендуется поставить множитель генерации NPC на 1.0, включить статических и динамических NPC. Это обеспечит постоянное присутствие рядом живых персонажей, с которыми можно взаимодействовать и набирать в свой отряд.

Встречаются и агрессивные NPC с огнестрельным оружием, которые могут неожиданно закончить путь даже опытного игрока. Также они любят воровать вещи.

Зарождение орды [ ]

По умолчанию все монстры генерируются вместе с местностью и после их смерти местность останется пустой.

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

Время года и сезоны [ ]

По умолчанию игра начинается на 30 день весны. Можно настроить по отдельности как стартовую дату (эволюция монстров и протухание продуктов не будут просчитываться), так и время, прошедшее от начала Катаклизма (тогда вышеупомянутые факторы будут просчитываться).

Начинать зимой - хардмод.

Длительность сезона по умолчанию 91 день.

Создание персонажа [ ]

Сценарий и профессия [ ]

Для новичка рекомендуется стандартный сценарий "Эвакуированный". Это старт в безопасном наземном убежище в отдалении от городов.

Профессия любая, лучше всего начать со стандартного "Выживший".

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

Черты [ ]

Положительные черты нужно компенсировать отрицательными.

Характеристики [ ]

Ловкость [ ]
Интеллект [ ]
Восприятие [ ]

Навыки [ ]

Стоит потратить по одному очку на навыки производства, шитья и выживания, чтобы можно было сразу заняться крафтом.

Первые шаги [ ]

Перед тем, как покинуть убежище, нам нужно создать защитную экипировку для всего тела и базовое оружие. Для этого мы используем доступные в помещении материалы.

Приятные мелочи [ ]

Палка [ ]

Подойди к окну, нажми e и сорви шторы. У тебя под ногами окажутся несколько предметов, нажми g и подбери палку. Нажми w и возьми палку в руки.

Нитки [ ]

Затем через B развяжи длинные шнуры на короткие, и пару коротких на нитки. Положи короткие шнуры и нитки в инвентарь.

Молоток [ ]

Подойди к шкафчикам и с помощью палки разбивай их через s , пока не выпадет кусок стали. Его можно использовать как примитивный молоток, положи его в инвентарь.

Стоя рядом с обломками шкафчиков, открой меню крафта & и сделай Прочее⟶шип из металлолома.

Швейная игла [ ]

Подойди к одной из лавок и через s разбей её на доски и гвозди. Стоя рядом с обломками лавки, открой меню крафта & и создай Прочее->деревянную иглу из расколотой доски.

Одежда [ ]

Вернись к окну и через B разрежь шторы на тряпки. Через d скинь с себя нижнее бельё и так же разрежь на тряпки.

Теперь через меню крафта & создай:

И надень всё это через W . Если крафт не удался, можно повторить попытку через - . Если закончились тряпки или нитки - разбери другое окно.

Оружие [ ]

В меню крафта & создай Оружие⟶копьё с наконечником. Как создавать шип, мы уже проходили с ножом, остальные ингредиенты должны валяться рядом, собери их вместе.

Продолжай шить вещи, которые можно разобрать на тряпки, пока не поднимешь навык шитья до третьего уровня. Обычно это занимает весь день, поэтому не выходи из убежища, кушай и пей то, что найдешь у себя в инвентаре и в здании. На ночь постели в подвале штору и засни на ней через $ . На третьем уровне шитья создай рюкзак, он значительно расширит инвентарь.

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

Еда, вода, алкоголь [ ]

Самый простой способ добыть еду, для которого понадобятся только палка и нож, - догнать и забить какую-нибудь живность, разделать и съесть сырое мясо.

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

В городах еда есть везде, особенно в бакалеях и различных закусочных и ресторанах.

Поедание фастфуда и несоблюдение баланса витаминов приводит к ухудшению здоровья.

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

Отшельники могут выращивать крупы и овощи на ферме.

Самый простой способ - забраться в дом и попить из унитаза. С большой вероятностью приводит к пищевому отравлению и также возможности заполучить паразитов.

Приготовить чистую воду можно в меню крафта, с помощью огня/электроплитки и кастрюли/открытой консервной банки. Либо закинув в ёмкость с водой таблетки для очищения, если такие нашлись.

Чтобы собирать дождевую воду, нужно изготовить воронку и поставить её (активировав через a ) на ёмкость типа бутылки.

Алкоголь [ ]

Полезный ресурс, в первую очередь как обезболивающее, поднимает моральное состояние, используется для изготовления самодельных медикаментов и коктейлей Молотова.

При чрезмерном употреблении вызывает рвоту, при регулярном - зависимость.

Скованность, боль, мораль, сон [ ]

Скованность [ ]

Несколько вещей на одном слое дают штраф.

Особенно выделяется скованность рта, которая замедляет восстановление выносливости. Бегать и сражаться в шлеме или шарфе это не лучшая идея.

В начале игры скованность должна быть в пределах 10-15, в дальнейшем допускается 25-30, если это оправдано степенью защиты.

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

Снижает скорость персонажа, не позволяя эффективно сражаться и передвигаться.

Повышается от ранений и болезней.

Обезболивающее - это первое, что всегда должно быть в инвентаре, самое доступное — алкоголь и аспирин.

Мораль [ ]

Низкая мораль не позволяет заниматься крафтом и чтением.

Лечится алкоголем и фастфудом.

Во время сна восстанавливаются повреждённые части тела.

Спать стоит в безопасных местах, например, подвале.

Закрытые помещения [ ]

Отмычки [ ]

Оружейный магазин [ ]

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

Лаборатория [ ]

Пропуск учёного [ ]
Напролом [ ]

Военный бункер [ ]

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

Приложение 1: Базовое управление [ ]

Полная информация о персонаже.

Такое же окно для NPC-друга можно открыть, заговорив с ним и выбрав пункт "Хочу узнать побольше о тебе".

Надетые и переносимые вещи. Доступный объём увеличивается за счёт сумок, рюкзаков и карманов на одежде. Максимальный вес зависит от силы.

Горячие клавиши для инвентаря

a (action) - использовать.

w (wield) - взять в руки.

T (take off) - снять.

E (eat) - съесть/выпить.

d (drop) - выбросить.

t (throw) - метнуть.

I - сравнить два предмета.

g (gather) - меню подбора окружающих предметов. Также можно воспользоваться продвинутым инвентарём / .

B (butcher) - разделать труп либо разобрать предмет;

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

e (examine) - меню изучения соседних клеток и взаимодействия с ними - набрать воду из реки, собрать ягоды с кустов, разжечь или потушить огонь в камине, взломать запертые двери и многое другое. Также можно использовать для подбора предметов.

s (smash) - ударить/разбить предмет на соседней клетке. Вероятность успешного разбивания зависит от силы персонажа и показателя ударного урона взятого в руки предмета. Можно разбивать трупы зомби вместо разделки.

x (explore) - режим осмотра, также можно использовать для этого мышку.

f - выстрел из оружия дальнего боя или удар копьём на расстоянии.

C (call) - обратиться к NPC или просто что-нибудь прокричать.

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

Также следи за скованностью рта - различные маски, шлемы и противогазы значительно замедляют восстановление выносливости и приводят к смерти.

Бег значительно увеличивает скорость передвижения по земле и при плавании, но и очень быстро тратит выносливость. Присед снижает скорость передвижения, но также снижает издаваемый персонажем при передвижении шум и позволяет прятаться за различными элементами обстановки (столами, диванами и т.д.). Обрати внимание, что в приседе дальность обзора персонажа снижается, так что он не сможет увидеть, к примеру, обстановку в доме, если крадучись подойдёт в окну.

Не забывай переключать бег или присед на ходьбу, когда эти режимы передвижения больше не нужны, так как очень легко забыть, что ты бежишь или крадёшься!

$ - лечь спать. Для этого нужна постель либо куча одежды на полу, а также усталость. Индикатор усталости появляется в правом верхнем углу.

Существует ряд факторов, которые не дают персонажу заснуть, например кофе или другие энергетики. Как снотворное можно использовать лекарство от кашля.

Во время сна восстанавливаются поврежденные части тела.

& - меню крафта. Необходимые ингредиенты для создаваемой вещи должны быть в инвентаре либо на расстоянии до 6 клеток в прямой видимости.

+ - полная информация о надетых вещах и слоях, которые они занимают.

m (map) - глобальная карта. Если включены орды зомби, они отображаются зелёными Z на карте.

Приложение 2: Машина с нуля [ ]

Постройка машины - очень трудоёмкий процесс, который потребует нескольких дней и большого количества еды.

Сначала нужно добыть следующие предметы:

Добываем детали [ ]

Найди подходящую машину-донор или несколько машин, с помощью инструментов демонтируй с них детали и складывай в кучу.

Сложнее всего снять колёса, потому что для этого нужно приподнять машину.

Есть три способа:

Каркас [ ]

В меню строительства

  • выбери пункт "Начать постройку транспорта" и поставь первую раму. Открой меню новой машины и поставь остальные 8 вокруг первой, должно получиться так:

Смонтируй 4 колеса по углам каркаса (передние должны быть управляемыми):

Корпус [ ]

Смонтируй 5 боковин и сиденье в центре:

Смонтируй 5 крыш в форме креста над сиденьем и смежными тайлами. Это обеспечит защиту водителя от дождя (тайл должен пометиться как Интерьер).

На тайл с сиденьем поставь руль и ремень безопасности.

Контейнеры [ ]

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

Например два сиденья и багажник в полу:

Двигатель, аккумулятор и бензобак [ ]

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

Освещение [ ]

Найди прожектор и поставь в центре крыши. Обычные фары не нужны.

Топливо [ ]

Найди машину с топливом либо заправку, подъедь на расстояние в один тайл и слей дизель/бензин с помощью резинового шланга. Если машина ещё не на ходу, используй контейнер.

Отличная машина для дальних путешествий и перевозки накопленного добра готова.

Мы - в Зоне

Награда за выполнение:
• Оружие и патроны: Пистолет Макарова 1 шт., Патроны 9х18 мм 60 шт.
• Костюмы: Кожаная куртка 1 шт.
• Рюкзаки: Вещмешок "Бархан" 1 шт.
• Еда и напитки: Хлеб 4 шт., Водка «Казаки» 1 шт.
• Медикаменты: Индивидуальная аптечка 1 шт., Бинт 3 шт.

Project Cataclysm | гайд group


Вадим Макаревич

Полезная штука, хм)

Нравится Показать список оценивших

Даниил Коваль

Нравится Показать список оценивших

Project Cataclysm | гайд group

Project Cataclysm | гайд group запись закреплена

всем привет, новостей не было давно т.к нету контента( но с обновлением все будет (и нет я не умер все хорошо )

Нравится Показать список оценивших

Project Cataclysm | гайд group

Project Cataclysm | гайд group запись закреплена

извините за долгие ответы админ заболел(

Нравится Показать список оценивших

Алиса Дятлова

Нравится Показать список оценивших

Project Cataclysm | гайд group

Project Cataclysm | гайд group запись закреплена

Нравится Показать список оценивших

Project Cataclysm | гайд group

Project Cataclysm | гайд group запись закреплена

Нравится Показать список оценивших

Project Cataclysm | гайд group

Project Cataclysm | гайд group запись закреплена

Квест "Разыскать информатора".
Берётся у Ореста.

Нравится Показать список оценивших

Project Cataclysm | гайд group

Project Cataclysm | гайд group запись закреплена

Секретный квест на который нужно 7 ИРП, находиться в баре, после взятия квеста просто следуем по меткам и после чего получаем 4к и 6 аптечек.


Удивительная переработка квестов в Cataclysm была вдохновлена дизайном квестов в Wrath of the Lich King. Не думаю, что кто-нибудь будет спорить, что сейчас квесты на вашем пути с 1-го по 60-й уровень могут быть лучше, чем они есть. Скучные квесты времён Ванилы ушли в прошлое, а на смену пришли захватывающие цепочки, которые раскрывают многие аспекты игры. Даже без наследуемых предметов прокачка ушла далеко от стандартной модели «Убей Х баранов» или «Собери Х частей баранов», которые раньше вызывали только отвращение у всех игроков. Такие локации как Темные берега, Азшара, Когтистые горы, Западный Край и Чумные Земли обзавелись значительными улучшениями в плане квестинга и самой истории, независимо от того, играете ли вы за Альянс или Орду. Квесты на подземелья теперь можно взять прямо внутри них (а в патче 4.3 это коснётся и Запределья с Нордсколом), и в каждой зоне теперь есть сильные и цельные квестовые цепочки, которые оставляют после себя уникальные ощущения.

Описывать каждую цепочку квестов и изменения всех зон было бы нерационально и в принципе почти невозможно. Будь то Бесплодные земли с разнообразными сюжетными линиями, или Фералас, где нам нужно справляться с наследием Драконов Кошмара – квесты стали намного интереснее и захватывающее. А самое главное изменение состоит в том, что квесты теперь строятся вокруг игрока и его места в мире. В тоже время важной их функцией является раскрытие всех изменений, которые принёс Смертокрыл в мир Азерота, вызвав ужасающий катаклизм, навсегда изменивший нашу планету. Кроме того, квесты призваны обратить наше внимание на разрастающийся каждую минуту конфликт между Ордой и Альянсом, а также — на внутренние конфликты этих фракций.

Всё это делается не только за счёт захватывающих квестовых цепочек, но и с помощью мелочей, которые окружают игрока повсеместно. Например, в Дуротаре два квестгивера, которые находятся возле Заставы Дранош'ар, Гор "Головорез" и Шин Каменостолб, больше спорят друг с другом, чем делают что-то ещё. В тоже время они раскрывают глубокое разделение внутри Орды между теми, кто поддерживает Тралла, и теми, кто вдохновлён военными успехами Гарроша.

Не обращай внимания на шамана, Солдат. Некоторые власть имущие из Орды приказали мне взять его с собой, но я уверяю тебя, что этот любящий Тралла шаман видит не дальше дверей этой хижины.

Именно такие мелочи помогают игрокам быстрей осознать подобные конфликты между различными силами.


Возможно, самое важное и замечательное место в прокачке (исходя из огромного количества вариантов, которые уступают друг другу лишь очень немного) – это опыт квестинга в Западном Крае. Здесь новые квесты являются продолжением истории, которая произошла ещё во времена классических квестов. Представленные как загадка об убийстве, Западный Край и новые квесты Братства совмещают в себе пафос, юмор, негодование, месть и повествуют о том, что случилось в этой локации и в остальном мире. Каждый, кто встречал Бригаду Западного Края в Седых Холмах, может оценить, как события собираются в единое целое, и понять, что действия Ванессы ван Клиф во время нападения Братства на Западный Край были простыми, но эффективными. Единственным разочарованием является внезапная кончина Ванессы в героической версии Мертвых Копей. Мне просто не хочется, чтобы её крайне интересная история заканчивалась так быстро.


Главным конкурентом Западного Края являются Когтистые Горы, где игрокам Орды предстояло пройти совершенно другие по своей манере, но не менее захватывающие квесты. Откровенно говоря, Когтистые Горы не представляли собой ничего особенного до переработки мира. Они были просто зоной, через которую вам приходилось быстро пробежаться и сделать пару квестов, которые не отличались каким-то креативом или загадкой. Но теперь независимо от того, нравится ли вам Орда Гарроша или нет, Когтистые Горы предоставляют вам уникальную возможность испытать на себе становление солдата Орды с самых низов прямо до вершин военной чести. Вы проходите путь от рубаки до проверенного временем и битвами воина и видите трагедию, развертывающуюся под командованием Властителя Кром'гара. Прямо перед вами раскрываются истинный характер и мотивы Орды и её Вождя. Вы узнаете, что сейчас, когда ситуация крайне сложная и удручающая, очень часто такие важные понятия, как честь и долг, проходят испытания. И не каждый может пройти это.

Что бы вы не чувствовали по отношению к Гаррошу Адскому Крику как игрок, квест Что значит быть Ордой… показывает его характер и его недостатки намного лучше, чем все рассказы и романы. Я не буду делать какие-то выводы, а сделаю кое-что другое. Призываю вас пройти этот квест и испытать лично всё это, если конечно есть такая возможность. В этом квесте есть всё: орки, интересная история, да и вообще всё, что возможно. Все грани характера Гарроша раскрыты: те, что достойны восхищения, и те, за которые может быть стыдно. Кроме того, становятся видны трещины, которые возникли в Орде после прихода Гарроша к власти. Данный квест стоит потраченного времени, по крайней мере, мне так кажется.

В Чумных Землях вас ждёт замечательные, глубокие и полные нюансов серии квестов, которые показывают, что даже Отрекшийся может прийти к осознанию безумия Сильваны, что таурен может помочь мне спасти жизнь дварфа, что Плеть, переставшая быть самой страшной угрозой мира, всё же не стоит на месте, и что зло процветает в местах больших и малых. В конце пути, Таренар Удар Солнца и Гидвин Златокос (NPC, которые мне крайне не понравились в начале цепочки) стали для меня если не друзьями, то точно уважаемыми компаньонами. Всем просто таки нужно увидеть, как изменились Чумные Земли после поражения Короля-Лича.


За время, проведённое в Cataclysm, я сформировал моё мнение насчёт этого дополнения. Оно сложилось не только за счёт игры на максимальном уровне, но и благодаря квестам, которые я проходил с 1-го по 60-й уровень. Я уже прокачал пару персонажей как за Орду, так и за Альянс, и теперь могу сказать точно, что прокачка моего главного персонажа первым, с 80-го по 85-й уровень, стала своего рода ошибкой. И это не потому, что квесты на этих уровнях плохи (хотя некоторые из них действительно мне не нравятся), а из-за того, что я потерял 60 уровней контекста к событиям, через которые я прошёл в Вайш’ире или Хиджале. Честно говоря, воинственность Орды в Вайш’ире или Сумеречном Нагорье обретает больше смысла, когда ты видишь как она продвигалась через Ясеневый Лес или Пустоши.


Рассказ о том, какими элегантными и захватывающими являются новые квесты, не будет полным без обсуждения двух моих любимых цепочек. Первая разворачивается в Фераласе и повествует о последних остатках драконов Кошмара, а вторая – в Выжженных Землях, которая является отличным продолжением классических квестов и заканчивается квестом Демон, имя тебе Рах'лих. Оригинальная цепочка квестов в Ваниле начиналась с Павшего героя Орды для Альянса и Орды и была занимательным примером дизайна квестов того времени. Вам предстояло облететь полмира туда и обратно, начиная с Выжженных Земель и заканчивая Азшарой.


Новые квесты стали достойными наследниками своих «предков». Они сосредотачиваются на новой тенденции в дизайне квестов и держат вас в одной локации от начала и до конца, таким образом, делая всё более рациональным и доступным. Как старые цепочки, так и новые дают вам отличный квестовый опыт, но новые – более ориентированы на соло прохождение. Тем не менее, что действительно меня поразило – это то, как новые квесты играют с вашими ожиданиями, когда вы проходите их первый раз. Они могут подтвердить некоторые ваши предположения, играют с другими, и, в конце концов, раскрывают судьбу персонажей, которых вы встречали в этой локации ещё до катаклизма. Если вы не проходили квесты в Выжженных Землях в Cataclysm, я настоятельно рекомендую вам это сделать, независимо от вашей фракционной принадлежности.

Picture 10

Скорее всего, из названия статьи вы уже догадались, что в центре внимания ошибки в исходном коде. Но это вовсе не единственное, о чем пойдет речь в этой статье. Если кроме С++ и ошибок в чужом коде вас привлекают необычные игры и вам интересно узнать, что это такие за «рогалики» и с чем их едят, добро пожаловать под кат!

В своем поиске необычных игр я наткнулась на игру Cataclysm Dark Days Ahead, отличающуюся от других необычной графикой: она реализована с помощью разноцветных символов ASCII на черном фоне.

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

Это игра с открытым исходным кодом, и, к тому же, написана на С++. Так что невозможно было пройти мимо и не прогнать этот проект через статический анализатор PVS-Studio, в разработке которого я сейчас принимаю активное участие. Сам проект удивил высоким качеством кода, однако, в нем все равно находятся некоторые недоработки и несколько из них я рассмотрю в этой статье.

К настоящему моменту с помощью PVS-Studio было проверено уже достаточно много игр. Например, вы можете ознакомиться с другой нашей статьей "Статический анализ в видеоигровой индустрии: топ-10 программных ошибок".

Логика

Следующий пример представляет собой типичную ошибку копирования.

V501 There are identical sub-expressions to the left and to the right of the '||' operator: rng(2, 7) < abs(z) || rng(2, 7) < abs(z) overmap.cpp 1503


Здесь дважды проверяется одно и то же условие. Скорее всего, выражение скопировали и забыли что-то в нём поменять. Я затруднюсь сказать, является ли эта ошибка существенной, но проверка работает не так, как задумывалось.

  • V501 There are identical sub-expressions 'one_in(100000 / to_turns <int> (dur))' to the left and to the right of the '&&' operator. player_hardcoded_effects.cpp 547

Picture 9

V728 An excessive check can be simplified. The '(A && B) || (!A && !B)' expression is equivalent to the 'bool(A) == bool(B)' expression. inventory_ui.cpp 199


Ошибки в условии нет, но оно излишне усложнено. Стоило бы сжалиться над тем, кому придется разбирать это условие, и написать проще if( left_fav == right_fav ).

  • V728 An excessive check can be simplified. The '(A && !B) || (!A && B)' expression is equivalent to the 'bool(A) != bool(B)' expression. iuse_actor.cpp 2653

Отступление I

Для меня оказалось открытием, что игры, которые на сегодняшний день называют «рогаликами» — это лишь достаточно лайтовые последователи старого жанра roguelike игр. Началось все с культовой игры Rogue 1980 года, ставшей образцом для подражания и вдохновившей множество студентов и программистов на создание собственных игр. Полагаю, многое также привнесло сообщество настольной ролевой игры DnD и её вариаций.

Picture 8

Микрооптимизации

Следующая группа предупреждений анализатора указывает не на ошибку, а на возможность микрооптимизации кода программы.

V801 Decreased performance. It is better to redefine the second function argument as a reference. Consider replacing 'const… type' with 'const… &type'. map.cpp 4644


Здесь за itype_id скрывается std::string. Так как аргумент все равно передается константным, что не позволит его изменить, быстрее было бы просто передать в функцию ссылку на переменную и не тратить ресурсы на копирование. И хотя, скорее всего, строка там будет совсем небольшая, но постоянное копирование без видимой на то причины излишне. Тем более, что эта функция вызывается из разных мест, многие из которых, в свою очередь, также получают type извне и копируют его.

  • V801 Decreased performance. It is better to redefine the third function argument as a reference. Consider replacing 'const… evt_filter' with 'const… &evt_filter'. input.cpp 691
  • V801 Decreased performance. It is better to redefine the fifth function argument as a reference. Consider replacing 'const… color' with 'const… &color'. output.h 207
  • В целом, анализатор выдал 32 таких предупреждения.

V813 Decreased performance. The 'str' argument should probably be rendered as a constant reference. catacharset.cpp 256


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

Это предупреждение также было не единичным, всего таких случаев нашлось 26.

Picture 7

  • V813 Decreased performance. The 'message' argument should probably be rendered as a constant reference. json.cpp 1452
  • V813 Decreased performance. The 's' argument should probably be rendered as a constant reference. catacharset.cpp 218
  • И так далее.

Отступление II

Некоторые из классических roguelike игр до сих пор активно развиваются. Если зайти в репозитории GitHub Cataclysm DDA или NetHack, то можно увидеть, что изменения активно вносятся каждый день. NetHack вообще является самой старой игрой, разработка которой идет до сих пор: её релиз произошел в июле 1987 года, а последняя версия датируется 2018 годом.

Одной из известных, однако, более поздних игр этого жанра является Dwarf Fortress, разрабатываемая с 2002 года и впервые выпущенная в 2006 году. «Losing is fun» («Проигрывать весело») — девиз игры, в точности отражающий её суть, так как победить в ней невозможно. Эта игра в 2007 году заслужила звание лучшей roguelike игры года в результате голосования, которое ежегодно проводится на сайте ASCII GAMES.

Picture 6

Кстати, тем, кто интересуется этой игрой, возможно будет интересна следующая новость. Dwarf Fortress выйдет в Steam с улучшенной 32-битной графикой. С обновлённой картинкой, над которой работают два опытных модера игры, премиум-версия Dwarf Fortress получит дополнительные музыкальные треки и поддержку Steam Workshop. Но если что, владельцы платной версии Dwarf Fortress смогут поменять обновлённую графику на прежний вид в ASCII. Подробнее.

Переопределение оператора присваивания

Примеры 5, 6:

Также нашлась интересная пара сходных предупреждений.

V690 The 'JsonObject' class implements a copy constructor, but lacks the '=' operator. It is dangerous to use such a class. json.h 647


Этот класс обладает конструктором копирования и деструктором, однако, для него отсутствует перегрузка оператора присваивания. Проблема здесь состоит в том, что автоматически сгенерированный оператор присваивания может лишь присвоить указатель к JsonIn. В результате оба объекта класса JsonObject указывают на один тот же JsonIn. Неизвестно, может ли где-то сейчас возникнуть такая ситуация, но, в любом случае, это — грабли, на которые рано или поздно кто-то наступит.

Аналогичная проблема присутствует в следующем классе.

V690 The 'JsonArray' class implements a copy constructor, but lacks the '=' operator. It is dangerous to use such a class. json.h 820


Более подробно об опасности нехватки перегрузки оператора присваивания для сложного класса можно почитать в статье "The Law of The Big Two" (или в переводе этой статьи "CИ++: Закон Большой Двойки").

Примеры 7, 8:

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

V794 The assignment operator should be protected from the case of 'this == &other'. mattack_common.h 49


Проблема в том, что данная реализация не защищена от присвоения объекта самому себе, что является небезопасной практикой. То есть, если этому оператору будет передана ссылка на *this, может произойти утечка памяти.

Схожий пример ошибочной перегрузки оператора присваивания с интересным побочным эффектом:

V794 The assignment operator should be protected from the case of 'this == &rhs'. player_activity.cpp 38


В этом случае точно так же отсутствует проверка на присваивание объекта самому себе. Но в дополнение заполняется вектор. Если попытаться такой перегрузкой присвоить объект самому себе, то в поле targets получим удвоенный вектор, часть элементов которого испорчена. Однако здесь перед transform присутствует clear, что очистит вектор объекта и данные будут потеряны.

Picture 16

Отступление III

В 2008 году рогалики даже обзавелись формальным определением, которое получило эпичное название «Берлинская интерпретация». Согласно этому определению, основными чертами таких игр являются:

  • Случайно сгенерированный мир, что увеличивает реиграбельность;
  • Permadeath: если ваш персонаж умирает — он умирает навсегда и все предметы теряются;
  • Пошаговость: изменения происходят только вместе с действием игрока, пока действие не произведено — время останавливается;
  • Выживание: ресурсы крайне ограничены.

Обычная ситуация в Cataclysm DDA: промерзли и голодны до смерти, вас мучает жажда, да и вообще у вас вместо ног шесть тентаклей.

Picture 15

Немаловажные детали

V1028 Possible overflow. Consider casting operands of the 'start + larger' operator to the 'size_t' type, not the result. worldfactory.cpp 638


Похоже, программист хотел избежать переполнения. Но приведение результата сложения в таком случае бессмысленно, так как переполнение возникнет уже при сложении чисел, и расширение типов произведется над бессмысленным результатом. Для того, чтобы избежать этой ситуации, необходимо привести лишь один из аргументов к большему типу: (static_cast<size_t> (start) + larger).

V530 The return value of function 'size' is required to be utilized. worldfactory.cpp 1340


Для таких случаев существует небольшая хитрость. Если переменная оказывается неиспользованной, вместо того, чтобы пытаться вызвать какой-либо метод, можно просто написать (void)world_name для подавления предупреждения компилятора.

V812 Decreased performance. Ineffective use of the 'count' function. It can possibly be replaced by the call to the 'find' function. player.cpp 9600


Судя по тому, что результат count сравнивается с нулем, идея в том, чтобы понять, есть ли хоть один требуемый элемент среди activity. Но count вынужден проходить по всему контейнеру, так как он считает все вхождения элемента. В этой ситуации будет быстрее использовать find, который останавливается после первого же найденного совпадения.

Следующая ошибка легко обнаруживается, если знать об одной тонкости.

V739 EOF should not be compared with a value of the 'char' type. The 'ch' should be of the 'int' type. json.cpp 762

Picture 3

Это одна из тех ошибок, которые бывает сложно заметить, если не знать, что EOF определен как -1. Соответственно, если пытаться сравнивать его с переменной типа signed char, условие почти всегда оказывается false. Единственное исключение, это если кодом символа будет 0xFF (255). При сравнении такой символ превратится в -1 и условие окажется верным.

Следующая небольшая ошибка однажды может стать критической. Не зря она есть в списке CWE как CWE-834. А их, кстати, было целых пять.

V663 Infinite loop is possible. The 'cin.eof()' condition is insufficient to break from the loop. Consider adding the 'cin.fail()' function call to the conditional expression. action.cpp 46


Как сказано в предупреждении, проверки на достижение конца файла при чтении недостаточно, необходимо также проводить проверку на ошибку считывания cin.fail(). Изменим код для более безопасного считывания:


keymap_txt.clear() нужен для того, чтобы при ошибке считывания из файла убрать из потока состояние (флажок) ошибки, иначе дальше считать текст будет нельзя. keymap_txt.ignore с параметрами numeric_limits<streamsize>::max() и управляющим символом перевода строки позволяет пропустить оставшуюся часть строки.

Есть и гораздо более простой способ остановки считывания:


Если использовать поток в контексте логики, он конвертирует себя в значение эквивалентное true, пока не будет достигнут EOF.

Отступление IV

Сейчас наибольшую популярность имеют игры, которые сочетают в себе признаки roguelike игр и других жанров: платформеров, стратегий и др. Такие игры стали называть roguelike-like или roguelite. К таким играм относят такие известные тайтлы, как Don't Starve, The Binding of Isaac, FTL:Faster Than Light, Darkest Dungeon и даже Diablo.

Хотя временами разница между roguelike и roguelite столь мала, что не понятно, к какому жанру отнести игру. Кто-то считает, что Dwarf Fortress уже не roguelike, а для кого-то и Diablo — классический рогалик.

Picture 1

Заключение

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

Picture 2

Над рассмотренной игрой и сейчас ведется активная работа, и существует активное сообщество моддеров. Причем она портирована на множество платформ, в том числе iOS и Android. Так что, если вас заинтересовала эта игра, рекомендую попробовать!

Читайте также: