Заглянул на сайт обучения программированию - живет! Это замечательно. Поддерживающим его людям - благодарность от всех десяти тысяч подписчиков!
Напоминаю, что сейчас я никаких курсов не веду и никаких комментариев по заданиям не даю. Но вы всегда можете зайти на сайт
http://prog-begin.net.ru/ , где вам ответы все же дадут :) На этом сайте ведутся форумы, где всем занимающимся, даются хорошие комментарии и помощь.
Торговля.
Следующий шаг по развитию нашей уже весьма солидной игры - это ввод в нее экономического элемента, торговли. Предметов на карте можно найти уже достаточно много (а в недалеком будущем мы введем очень популярный в ролевых играх прием, когда из убитого монстра выпадают полезные предметы и деньги; почему это делается позже, а не сейчас, станет понятно из дальнейшего текста), но копить их не имеет смысла, так как со многими распорядиться не удастся. Так, магу не нужен меч, а воину - магические заклятья. Поэтому
накопленные предметы желательно продавать, а на вырученные деньги приобретать что-то более подходящее по классу.
Для начала введем в игру такое понятие, как деньги. Деньги - это, очевидно, предмет, его можно носить в инвентаре. Добавим новый тип данных itemMoney:
type TGameItemType = (itemHandWeapon, itemArmor,
itemAmmo, itemRangedWeapon, itemMagik, itemMoney, itemNone);
Компилятор нам напомнит, что надо указать символ, отображающий деньги на карте. Напрашивающиеся символ и цвет очевидны:
Также в процедуру генерации карты MapGeneration, в часть, ответственную за случайное распределение предметов, добавим возможность разбрасывания по карте денег (для чего надо уточнить их количество).
if Items[n].ID = 7 then begin
... end else
if Items[n].ID = 8 then begin
end
По какому принципу разбрасывать деньги по карте? Ведь в начале игры и один золотой будет серьезным подспорьем, а в середине, возможно, и тысяча монет покажется мелочью. Было бы неплохо сумму на земле рассчитывать относительно суммы, которая у героя уже имеется. Однако генерация карты выполняется до генерации героя, поэтому привяжем сумму к текущему "уровню" карты, параметру процедуры MapLevel. Условимся, что сумма будет равняться случайному числу от 1 до MapLevel*10 золотых:
if Items[n].ID = 8 then begin
Items[n].Ints[intMoney] := random(MapLevel*10)+1; end
А как будет происходить подбор денег?
Предварительно для удобства договоримся, что деньги не могут храниться как "разные" предметы, в разных слотах инвентаря. Если они подбираются с земли или поступают из других источников, то их необходимо объединить с уже имеющимися.
Такая функция, скорее всего, будет востребована в разных местах нашего кода, поэтому выделим ее в отдельную подпрограмму. Пусть функция GetMoneyNo (модуль Hero) возвращает номер слота инвентаря героя, в котором хранятся золотые, либо отрицательный номер свободного слота, если денег у героя нету, либо 0, если все слоты заняты:
{ ----------------- } function GetMoneyNo( var H: THero ): Integer; var i, ss: Integer; begin
ss := 0; for i := 1 to MaxHeroItems do if H.Items[i].IType = itemMoney then begin
GetMoneyNo := i;
Exit end else if H.Items[i].IType = itemNone then if ss = 0 then
ss := -i;
GetMoneyNo := ss
end;
Дополнительная проверка на равенство ss (номер свободного слота) нулю нужна, чтобы находился самый первый свободный слот.
Этой функцией воспользуемся в процедуре подбора денег. Нам придется модифицировать процедуру GetItemFromMap, потому что в начале ее происходит поиск свободного слота, и если он не находится, процедура сразу завершается. Однако теперь возможна ситуация, когда все слоты заняты, однако в одном из них хранятся деньги, и золотые также подбираются с земли. Поэтому измененная подпрограмма подъема предметов с земли запишется так:
{ ----------------- } procedure GetItemFromMap; var i, n: Integer; begin for i := 1 to MaxItems do if (Heroes[CurHero].x = Items[i].x) and
(Heroes[CurHero].y = Items[i].y) then begin
if Items[i].IType = itemMoney then begin
n := GetMoneyNo(Heroes[CurHero]); if n = 0 then Exit;
if n > 0 then
inc( Heroes[CurHero].Items[n].Ints[intMoney],
Items[i].Ints[intMoney] )
else Heroes[CurHero].Items[-n] := Items[i];
ShowInfo( STR_GETMONEY + IntToStr(Items[i].Ints[intMoney]) ); end else
begin
n := GetFreeBag(Heroes[CurHero]); if n = 0 then Exit;
ShowInfo( STR_GETITEM + Items[i].Name );
Heroes[CurHero].Items[n] := Items[i]; end;