RU

Помощь в создании "Асатамы III"

mkir #1281 16.01.2020 14:00 59 comments 15499 views

Спустя годы я все-таки вновь возвращаюсь к мысли создать еще более глобальную и интересную игру в этой серии, несмотря на то, что, возможно, это практически никому не интересно (а вдруг станет интересно?). (и вообще я так понимаю в целом в “сообществе любителей текстовых игр” тишина, или это поверхностное впечатление?)

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

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

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

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

ЧТО ИМЕЕМ

1. Есть переменная $mon=‘’ - это имя монстра.
Когда игрок нападает на монстра, мы присваиваем ему имя, а затем переходим в служебную одноименную локацию gs ‘mon’
В ней содержатся все данные о любом монстре, выглядят это так:

if $mon = 'Крыса':
hp = 10
st = 10
... и так далее
end

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

2 Когда игрок находится в свободном плавании, он рискует столкнуться со случайным монстром. Это зависит от типа локации “Лес”, “Поле”, “Горы” и т.д., и сложности конкретного отрезка местности - “1, 2, 3…”. Т.е. если игрок в лесу и сложность 1, он будет встречать всяких зайчиков и оленей и в худшем случае какого-нибудь волка повстречает. Если он в горах и сложность максимальная, то встретит какого-нибудь убер-страшного горного великана. А некоторые монстры могут встречаться сразу в нескольких типах местностях - разбойник, например. Также некоторые монстры могут встречаться на нескольких уровнях сложности. Т.е. мы не обязательно столкнемся с тем горным великаном, вполне, что за поворотом затесался горный козлик, мирно жующий травку. +какие монстры при одинаковых условиях встречаются реже или чаще остальных.

Сам код в этом месте определения монстра получился у меня жутко неудобным. Я просто на отдельной локации “checkmon” настраивал множество условий и вероятностей, типа:

if местность = лес:
	if сложность = 1:
	х=rand(1,12)
		if x < 2:
		$mon='Заяц'
		end
		if x > 1 and x < 5:
		$mon='Разбойник'
			if rand(1,100) > 80:
			$mon = 'Матерый разбойник'
			end
		end
		if x > 4:
		$mon = 'Волк'
		end
		if x = 12:
		$mon = 'Медведь'
		end
	end
	if сложность = 2:
	!то же самое, но если хотим чтобы какой-нибудь заяц встречался и здесь, то также вручную добавляем и его:)
	end
end

Итого, при том что монстров очень много и условий то же, все это со временем превратилось в кашу.

ЧТО ХОЧЕТСЯ РЕАЛИЗОВАТЬ

Я представляю себе это так: есть некий пакет с именами монстров и с их “полевыми характеристиками”, типа каким местностям они свойственны, какая у них максимальная и минимальная планка сложности и какой уровень редкости.

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

Вот как такой пакет “написать” без полного погружения меня в мир массивов :)
И какая должна быть команда в момент столкновения игрока с монстром и может ли она уместиться в одну строчку?

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

Знать бы как! Да и ломать то, что уже сделано, под новый инвентарь, нет желания. В общем, если отвечать на вопрос, - можно сказать, что тем, что предлагает стандартный qsp, сделать сортировку невозможно?

mkir,
Дык я уже присылал тебе образец, в т.ч. и с сортировкой, даже интегрированный, но, конечно не полностью. Правда, не через obj.

Попробуй индекс вручную писать, для оружия со 100, для спутников с 1000

ADDOBJ [$название],[$путь к файлу изображения],[#индекс] - добавление предмета с названием [$название] и изображением [$путь к файлу изображения] в инвентарь на место с номером [#индекс].
Параметр [$индекс] может отсутствовать. По умолчанию предметы добавляются в конец списка.
Индексация предметов рюкзака ведётся с 1.

Aleks Versus Moderator 30.06.2020 14:58 (5 years ago)

mkir,
сортировка возможна. Это сто процентов. Если тебе нужно конкретное решение, нужно знать, как у тебя точно организовано добавление/удаление предметов. Есть функции countobj, $getobj, которые помогут в сортировке. По хорошему, нужно хранить объекты и их свойства в разных массивах, и можно сортировать по любому из свойств.

Aleks Versus,
Список предметов в окне предметов отображается по индексу, соответственно, чтоб провести сортировку этого окна нужно переписывать индексы. Или нет?

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

addobj'Предмет','',индекс

Вместо индекса ставишь число, которое соответствует позиции строчки меню Напарники(меню должно быть пустое, без предметов). Все предметы будут появляться выше).
Это костыль, т.к. индексы предметов будут меняться и невозможно будет что-то к индексу привязать.

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

Дописывать индекс всем уже проставленным addobj - было бы мучительно)

mkir,
Сделай проверку. Добавь предмет, потом добавь спутника, потом продай предмет. Если все будет работать как надо, то ок.

Aleks Versus Moderator 02.07.2020 18:27 (5 years ago)

dmvikar,
всё верно. Но можно написать и обратную функцию, чтобы ПОЛУЧИТЬ индекс уже добавленного предмета. Тогда сортировка будет гораздо точнее. И само меню, написанное в окне предметов, можно будет разбить на сколь угодно большое число разделов (в пределах разумного). Для этого я и привёл функцию countobj. Если мы знаем число предметов в окне предметов, мы можем перебрать их с помощью цикла, получая названия через $getobj(i), и выяснить, под каким индексом записан предмет “Спутники”, под каким “Инвентарь”, и т.д. Далее — дело техники добавить предмет в позицию после найденного индекса.

Aleks Versus,
Понял, спс.
Я не ожидал, что добавление строки с существующим индексом раздвигает массив, а не заменяет строку, пока не определил методом тыка), так и родился вариант выше.
Для меня все-равно не очень понятна сортировка объектов через отдельный массив свойств. Я всегда делаю это через индексы, т.е. предмет[i]и свойство[i], как в таком случае сопоставлять массивы, если i предмета будет меняться. Делать свойство{’предмет’]? Тогда предметы с одинаковым именем будут всегда иметь одинаковые свойства…
Короче, использую я обычные переменные для инвентаря и отдельную локацию. Можно выводить таблицу любой подробности и осуществлять сортировку в самой игре по любому из свойств.

mkir,
Если пунктов меню, под которые нужно будет добавлять предметы будет больше двух или сами пункты будут меняться местами, то понадобится такой код:

a=1
:mark
if $getobj(a)='Нужный пункт меню':
индекс=a &!позиция перед пунктом
индекс=a+1 &!позиция после пункта
addobj'Предмет','',индекс
else
a+=1
jump'mark'
end

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

Aleks Versus Moderator 04.07.2020 09:58 (5 years ago)

dmvikar,
есть вариант сортировать массив свойств и сразу параллельно этому переставлять значения во втором массиве. Либо ввести третий массив — опорный, в который прописываем индексы в процессе сортировки. Например был у нас массив из трёх элементов 0, 1, 2, а после сортировки элемент с индексом 2 оказался в нулевой ячейке, элемент с индексом 0 оказался в первой, а с индексом 1 — в последней. В опорном массиве будут храниться эти индексы 2, 0, 1. И будь у тебя ещё хоть десять других массивов, по опорному можно перетасовать их все.

Короткий пример datasort.qsp. На самом деле он и правда короткий, просто для наглядности я оставил повторяющийся код.

Смотрите. У меня есть предмет “Лисья шерсть”, к нему прикреплен вот такой код:

if selobj = 'Лисья шерсть':
unsel
pl 'Осталось <<шерсть>> шерсти. Нажми <a href="EXEC:шерсть-=1&hp=hpboard&stboard=45+(6*sk_st)&st=stboard&mn=mnboard&clr&gt $curloc">сюда</a>, чтобы потратить единицу для полного восстановления'
end

Чисто любопытства ради поменял pl на msg — думая, а возможно ли сделать ссылки в msg (не надеясь, что да, мне это нужно для другого — чтобы вместо простого “ок” были принудительные варианты). Но получилось что-то совсем неожиданное — при нажатии на “сюда”, вместо выполнения кода программа хочет что-то открыть, скриншот прилагаю.

На win7 msg выводит ссылку, только клик по ней ничего не дает. Наверно потому, что код во время открытого окна msg не выполняется.

EXEC для ссылок в MSG и INPUT не поддерживается.

Log in or Register to post comments.