Как сделать?
…
Я использовал плеер 5.7, скачал последний 5.9.3, в нем все работает (моя вина). Но спасибо, всем! Простите, не заметил что форум ушёл на следующую страницу и только сейчас увидел ваши ответы (отвык от форумов).
Подскажите, пожалуйста
Правильно ли я понимаю, что я не могу сделать итерацию не по всему массиву, а по ячейке массива. То есть “многомерные” массивы по сути не совсем многомерные, это те же линейные массивы, только с кортежами в качестве индекса.
Например, я создаю массив
LOCAL Q_INDEX = 0
$QUESTS_TEXT[Q_INDEX] = "Иди туда, не знаю куда и принеси то, не знаю что"
LOCAL STEP_INDEX = 0
$QUESTS_STEPS[Q_INDEX, STEP_INDEX, "todo"] = "Идти туда, не знаю куда"
QUESTS_STEPS[Q_INDEX, STEP_INDEX, "done"] = 1
STEP_INDEX += 1
$QUESTS_STEPS[Q_INDEX, STEP_INDEX, "todo"] = "Принести то, не знаю что"
QUESTS_STEPS[Q_INDEX, STEP_INDEX, "done"] = 0
Я в таком случае не могу узнать сколько в QUESTS_STEPS[QUEST_INDEX] хранится элементов, и соответственно проитерироваться? Мне нужно хранить условно еще один массив для квестов, где для каждого квеста помнить сколько у него есть шагов, типа QUESTS_STEPS_COUNT[QUEST_INDEX] = 2. И тогда брать эту переменную и с помощью нее итерироваться?
Да, верно. Можно итерироваться по всему массиву (обойти вообще все элементы) или хранить число элементов в каком-то “измерении” отдельно.
Для упрощения работы можно создать специальные служебные локации и вызывать через @/@@, но это будет работать медленнее.
Альтернативный вариант (на мой взгляд он лучше) - хранить элементы измерений, по которым нужно итерироваться, в разных массивах.
Всем привет, может для ветеранов вопрос глупый, но объясните пожалуйста.
Допустим, есть описание локации. Есть действие “осмотреться”, которое в описание выводит пару строк о том, что происходит вокруг через *PL. Так вот, объясните пожалуйста, как сделать так, чтобы описание которое выдается после этого действия выводилось после основного текста, а не перед ним?
Gvozd229, привет, можно пример кода, или подробней описать? Просто любой текст выводится после основного текста по умолчанию.
Gvozd229, а, что ты подразумеваешь под “основной текст”?
Все операторы идут друг за другом, так что любой следующий вывод следует за предыдущим в порядке появления в коде. Поэтому смотри порядок операторов.
Действия через ACt выводятся в отдельном окне (окно действий), и как-то комбинировать их с основным окном может только пользователь. Но можно действия оформить как ссылки внутри текста - ну и тогда располагать их как угодно относительно текстовых блоков. Пример - ‘<a href=“EXEC:любойисполняемыйкод”>НАЗВАНИЕ ДЕЙСТВИЯ</a>’
mkir:
Действия через ACt выводятся в отдельном окне (окно действий), и как-то комбинировать их с основным окном может только пользователь.
Имярек немного за другое говорит. Любое Действие может выводить дополнительный текст и этот текст будет продолжением уже выведенного. У камрада отчего-то текст при выполнении Действия выводится перед основным текстом страницы (на сколько я понял из объяснений). Могу предположить, что код выглядит примерно так:
Act 'Новая строка': *P "Балаболка"
*P "Абракадабра и кадабра абра"
Я давно отказался от “Прямого” вывода текста в КуСПе. Я сначала полностью формирую строку и только потом вывожу. Если мне надо что-то убрать или добавить, то сначала “строка” будет переформатирована и только потом выведена. Что и как выводить передаю самому себе в виде аргумента. Это избавляет от огромного числа “киноляов”. Иногда строку формирую вообще динамически, вплоть до применяемых операторов и операндов. Перед каждым формированием и выводом ставлю Действие “Спасение”, чтобы при возникновении ошибки можно было вернуться в игру, а не “зависнуть в чистом поле”.
Примерно так - простейшее формирование (статическое) нужной строки:
[b]# Кузница[/b]
SHOWSTAT Off
Act 'Спасение': GT 'Домой' & !Создание Действия возврата на основную локацию
$FullStr=Func($CurrentLocation) & !Получаем строку вывода (Приводить не буду, идет простой перебор в цикле и вывод по очереди формирования в зависимости от нужной локации
$FullStr & !Вывод полученной строки
If $CurrentLocation='Снаряжение':
Act 'Собрать инвентарь': Gs 'Get_Ammo_BlackSmith' & Gt 'Кузница' & !Выполняем действие (идет случайный подбор инвентаря) и возвращаемся на локацию
Act 'Продавать | Улучшать' : $CurrentLocation='Снаряжение_Героя' & $CurrentAmmo='' & Gt 'Кузница' & !Выполняем действие (переходим к выбору снаряжения у ГГ) и возвращаемся на локацию
Act 'Назад ': КПокупке=Off & Gt 'Домой'
End
If $CurrentLocation='Снаряжение_Героя':
Act 'Покупать' : $CurrentLocation='Снаряжение' & КПокупке=On & $CurrentAmmo='' & Gt 'Кузница' & !Выполняем действие и возвращаемся на локацию
End
If $CurrentLocation='Апгрейд_Снаряжения':
Act 'Покупать' : $CurrentLocation='Снаряжение_Кузни' & $CurrentAmmo='' & Gt 'Кузница' & !Выполняем действие и возвращаемся на локацию
Act 'Назад' : $CurrentLocation='Снаряжение_Героя' & Gt 'Кузница'
End
Delact 'Спасение' & !Удаление Действия (Код локации отработал правильно или не вызвал критической ошибки)
[b]--- Кузница ---[/b]
Пример динамического формирования выводимого:
!Локация Создания персонажа
!SHOWACTS On & !Включаем окно Действий
Local $ResStr
Local $RaceStr
Local $NameLeft, $NameRight, $NameInput
Local $GenderLeft, $GenderRight
Local $RaceLeft, $RaceRight, $RaceReset
Local $PhotoLeft, $PhotoRight, $PhotoReset
Local $РостLeft, $РостRight
*Clr & !Чистим поле
CLA & !Удаляем Действия
If $Args[0]='First': & !Формирование при "первом посещении" локации
CopyArr 'Player','NPC'
CopyArr 'Tempo','NPC'
!@CopyRacePreset('Tempo','Player') & !Копируем нужные предустановки
GoPresets=On
!@Случайный_Пресонаж(On, On, On)
Player['Раса']=Rand(0,6)
Player['НомерФото']=Rand(RaceSize[Player['Раса']])
@CopyRacePreset('Player',$Race[Player['Раса']]+'_0')
@CopyRacePreset('Player',$Race[Player['Раса']]+'_'+Player['НомерФото'])
SHOWACTS On & !Открыть окно Действий
PercSelected=Off & !Результат выбора перков.
End
! Динамическое формирование нужных операторов.
$NameLeft="If Player[''НомерИмя'']<=0:
Player[''НомерИмя'']=ArrSize(''$''+$Race[Player[''Раса'']]+''_Имя'')-1
Else
Player[''НомерИмя'']-=1
End
$Player[''Имя'']=ArrItem(''$''+$Race[Player[''Раса'']]+''_Имя'',Player[''НомерИмя''])"
$NameRight="If Player[''НомерИмя'']>=ArrSize(''$''+$Race[Player[''Раса'']]+''_Имя'')-1:
Player[''НомерИмя'']=0
Else
Player[''НомерИмя'']+=1
End
$Player[''Имя'']=ArrItem(''$''+$Race[Player[''Раса'']]+''_Имя'',Player[''НомерИмя''])"
$NameInput="$RaceStr=Input(''Введите имя персонажа:'')
$RaceStr=$Replace($RaceStr, '' '')
If $RaceStr<>'''' and $RaceStr<>$Player[''Имя'']:
$Player[''Имя'']=$RaceStr
Player[''НомерИмя'']=-1
End"
$GenderLeft="If Player[''Гендер'']<=0 : Player[''Гендер'']=1 Else Player[''Гендер'']-=1"
$GenderRight="If Player[''Гендер'']>=1 : Player[''Гендер'']=0 Else Player[''Гендер'']+=1"
$RaceLeft="If Player[''Раса'']<=0 : Player[''Раса'']=6 Else Player[''Раса'']-=1"
$RaceRight="If Player[''Раса'']>=6:Player[''Раса'']=0 Else Player[''Раса'']+=1"
$RaceReset="If Player[''НомерФото'']>RaceSize[Player[''Раса'']]:Player[''НомерФото'']=1
@CopyRacePreset(''Player'',$Race[Player[''Раса'']]+''_0'')
If GoPresets=On : @CopyRacePreset(''Player'',$Race[Player[''Раса'']]+''_''+Player[''НомерФото''])
If Player[''НомерИмя'']>-1 :
If Player[''НомерИмя'']>=ArrSize(''$''+$Race[Player[''Раса'']]+''_Имя'') : Player[''НомерИмя'']=ArrSize(''$''+$Race[Player[''Раса'']]+''_Имя'')-1
$Player[''Имя'']=ArrItem(''$''+$Race[Player[''Раса'']]+''_Имя'',Player[''НомерИмя''])
End"
$PhotoLeft="If Player[''НомерФото'']<=1:Player[''НомерФото'']=RaceSize[Player[''Раса'']] Else Player[''НомерФото'']-=1"
$PhotoRight="If Player[''НомерФото'']>=RaceSize[Player[''Раса'']]:Player[''НомерФото'']=1 Else Player[''НомерФото'']+=1"
$PhotoReset="If GoPresets=On : @CopyRacePreset(''Player'',$Race[Player[''Раса'']]+''_''+Player[''НомерФото''])"
! Формирование "строки" вывода
$ResStr=@Заголовок('Создание персонажа')
$ResStr+='<center><table width=1250 <<$AlignLeft>> border=0 cellspacing=0 cellpadding=0>'
$ResStr+='<tr>'
$ResStr+='<td width=400 <<$AlignLeft>>>'
$ResStr+='<table width=300 <<$AlignLeft>> border=0 cellspacing=0 cellpadding=0>'
$ResStr+='<tr>' & !Строка имени
$ResStr+='<td width=60 <<$AlignCLeft>>>'
$ResStr+='Имя:'
$ResStr+='</td>'
$ResStr+='<td width=24 <<$AlignCLeft>>>'
$ResStr+='<a href="exec: Dynamic(''<<$NameLeft>>'') & Gs(''Создание_Персонажа'')"><img src=".\pic\GLeft.png" height=24></a>'
$ResStr+='</td>'
$ResStr+='<td width=252 <<$AlignCenter>>>'
$ResStr+='<a href="exec: Dynamic(''<<$NameInput>>'') & Gs(''Создание_Персонажа'')" >'
If Player['НомерИмя']=-1 and $Player['Имя']='???' :
$ResStr+='Введите имя</a>'
Else
$ResStr+='<<$Player["Имя"]>></a>'
End
$ResStr+='</td>'
$ResStr+='<td width=24 <<$AlignCRight>>>'
$ResStr+='<a href="exec: Dynamic(''<<$NameRight>>'') & Gs(''Создание_Персонажа'')"><img src=".\pic\GRight.png" height=24></a>'
$ResStr+='</td>'
$ResStr+='</tr>'
$ResStr+='<tr>' & !Строка Расы
$ResStr+='<td width=60 <<$AlignCLeft>>>'
$ResStr+='Раса:'
$ResStr+='</td>'
$ResStr+='<td width=24 <<$AlignCLeft>>>'
$ResStr+='<a href="exec: Dynamic(''<<$RaceLeft>>'') & Dynamic(''<<$RaceReset>>'') & Gs(''Создание_Персонажа'')"><img src=".\pic\GLeft.png" height=24></a>'
$ResStr+='</td>'
$ResStr+='<td width=252 <<$AlignCenter>>>'
$ResStr+='<<$RaceName[Player[''Раса'']]>>'
$ResStr+='</td>'
$ResStr+='<td width=24 <<$AlignCRight>>>'
$ResStr+='<a href="exec: Dynamic(''<<$RaceRight>>'') & Dynamic(''<<$RaceReset>>'') & Gs(''Создание_Персонажа'')"><img src=".\pic\GRight.png" height=24></a>'
$ResStr+='</td>'
$ResStr+='</tr>'
$ResStr+='<tr>' & !Строка Пол
$ResStr+='<td width=60 <<$AlignCLeft>>>'
$ResStr+='Пол:'
$ResStr+='</td>'
$ResStr+='<td width=24 <<$AlignCLeft>>>'
$ResStr+='<a href="exec: Dynamic(''<<$GenderLeft>>'') & Gs(''Создание_Персонажа'')"><img src=".\pic\GLeft.png" height=24></a>'
$ResStr+='</td>'
$ResStr+='<td width=252 <<$AlignCenter>>>'
$ResStr+=$Гендер[Player['Гендер']]
$ResStr+='</td>'
$ResStr+='<td width=24 <<$AlignCRight>>>'
$ResStr+='<a href="exec: Dynamic(''<<$GenderRight>>'') & Gs(''Создание_Персонажа'')"><img src=".\pic\GRight.png" height=24></a>'
$ResStr+='</td>'
$ResStr+='</tr>'
$ResStr+='<tr>' & !Пустая строка
$ResStr+='<td>'
!$ResStr+='<br>'
$ResStr+='</td>'
$ResStr+='</tr>'
....
$ResStr+='Навык метательного оружия: <b><<Player[''НавыкНож'']+Бонус[''НавыкНож'']>></b><br><br>'
...
$ResStr+='</td>'
$ResStr+='<td width=350 <<$AlignCenter>>>' & !Вывод картинки
$ResStr+='<table width=350 <<$AlignLeft>> border=0 cellspacing=0 cellpadding=0>'
$ResStr+='<tr>'
$ResStr+='<td width=350 <<$AlignCTop>>>'
$ResStr+='<img src="<<@GetMidlPicture(Player[''Раса''],Player[''НомерФото''])>>" height=400>'
$ResStr+='</td>'
$ResStr+='</tr>'
$ResStr+='</table>'
$ResStr+='<table width=200 <<$AlignCenter>> border=0 cellspacing=0 cellpadding=0>'
$ResStr+='<tr>'
$ResStr+='<td width=24 <<$AlignCLeft>>>'
$ResStr+='<a href="exec: Dynamic(''<<$PhotoLeft>>'') & Dynamic(''<<$PhotoReset>>'') & @Создание_Персонажа"><img src=".\pic\GLeft.png" height=24></a>'
$ResStr+='</td>'
$ResStr+='<td width=148 <<$AlignCenter>>>'
$ResStr+='Выбор вида'
$ResStr+='</td>'
$ResStr+='<td width=24 <<$AlignCRight>>>'
$ResStr+='<a href="exec: Dynamic(''<<$PhotoRight>>'') & Dynamic(''<<$PhotoReset>>'') & @Создание_Персонажа"><img src=".\pic\GRight.png" height=24></a>'
$ResStr+='</td>'
$ResStr+='</tr>'
$ResStr+='</table>'
$ResStr+='</td>'
$ResStr+='</tr>'
$ResStr+='</table></center>'
$ResStr & !Вывод полученной строки
Act 'Создать случайного персонажа': @Случайный_Пресонаж(GoPresets, On, On) & @SetBonus & @Создание_Персонажа
If PercSelected<>On : Act 'Перейти к выбору перков': Gt 'Выбор_Перков' Else Act 'Изменить выбор перков': Gt 'Выбор_Перков'
If $Player['Имя']<>'' and $Player['Имя']<>'???' and PercSelected=On and Бонус[BonusCount+1]<>0 and Бонус[BonusCount+2]<>0 and Бонус[BonusCount+3]<>0 :
Act @Цвет('Принять выбор и играть',ЗЕЛ,'b'): @Персонаж_Создан & Gt 'Письмо'
Else
Act @Цвет('Принять выбор и играть',СЕР):
Local $MsgStr=''
If $Player['Имя']='' or $Player['Имя']='???' : $MsgStr+='Не задано имя Пресонажа<br>'
If PercSelected<>On : $MsgStr+='Не выбраны перки<br>'
If Бонус[BonusCount+1]=0 or Бонус[BonusCount+2]=0 or Бонус[BonusCount+3]=0 : $MsgStr+='Не выбраны cтартовые бонусы'
Msg($MsgStr)
End
End
Выглядит примерно так:
При нажатии на любую ссылку происходит изменение значения и возврат на локацию с полным переформированием строки вывода… и так по кругу, пока не отработает Дейстивие “Принять и Играть”
Помогите, плиз, понять многомерные массивы. Я, возможно, глупая, но я так и не поняла для чего они. Я читала в справке о них, но так и не поняла. Пожалуйста, объясните зачем они нужны? Как их использовать? Для чего нужны значения, что находятся вместо номеров ячеек? Как их использовать?
Хотя, возможно, я пока замахнулась на слишком сложную тему для себя, поэтому не могу пока понять, но всё же хотелось бы хоть немного понять многомерные массивы
Многомерные массивы полезны в случае, когда какое-либо значение нужно связать не с одним значением, а с несколькими.
Например, если описание какого-то предмета зависит только от порядкового номера предмета (м.б. от его названия?), то это одномерный массив.
Если описание предмета зависит не только от номера предмета, а еще и от локации, где игрок находится, то это уже двухмерный массив (в этом случае предмет с одним порядковым номером может иметь разное описание в зависимости от локации).
Другой пример - у нас есть двухмерная карта с координатами. Тогда содержимое каждой ячейки будет зависеть от 2х координат - это двухмерный массив (как таблица).
Если добавить еще одно измерение (например, содержимое _каждой_ ячейки карты зависит от координаты Z или от другого обязательного параметра), то это будет 3х-мерный массив.
Измерений может быть много, главный критерий создавать их или нет - это от скольких/каких _обязательных_ параметров зависит значение каждого элемента массива.
В QSP с этим немного проще, т.к. в пределах одного массива одна ячейка может зависеть от любого числа параметров (какие-то значения могут быть для 1го, другие для 2х, и т.д.)
Использовать это просто - нужно вместо одного значения-индекса массива, указать несколько через запятую.
Установка значения:
$описание[x,y]='это описание для ячейки x,y'
Использование значения:
pl $описание[x,y]
! другой немного странный пример:
if $локация[x,y]='крыша': pl 'Вы находитесь на крыше высокого здания'
Значение ячейки может зависеть от значений разных типов:
$описание[x,y,$value]='это описание для ячейки по переменным x,y,$value'
$описание['test', x]='это описание для ячейки "test",x'
Конечно, в качестве индексов можно использовать значения из других массивов (то есть, не просто переменные/константы).
ShadowX2,
На мой взгляд самый простой способ понять многомерный массив можно на примере шахматной доски.
Есть некая “Длина” и некая “Ширина”. В шахматах это буквы: A,B,C,D,E,F,G,H и цифры 1,2,3,4,5,6,7,8. Каждая ячейка может быть или черная или белая, и в каждой ячейке у тебя может был какая-то фигура или ячейка пустая.
Тогда, классическая форма многомерного шахматного массива в КуСПе будет выглядеть примерно так (Условно):
$Доска['A',1,'Фигура']=$ЛадьяБел[1]
$Доска['A',1,'Цвет']='Черный'
$Доска['B',1,'Фигура']=$КоньБел[1]
$Доска['B',1,'Цвет']='Белый'
$Доска['С',1,'Фигура']=$СлонБел['Черный']
$Доска['C',1,'Цвет']='Черный'
$Доска['D',1,'Фигура']=$ФерзьБел
$Доска['D',1,'Цвет']='Белый'
$Доска['E',1,'Фигура']=$КорольБел
$Доска['E',1,'Цвет']='Черный'
$Доска['F',1,'Фигура']=$СлонБел['Белый']
$Доска['F',1,'Цвет']='Белый'
$Доска['G',1,'Фигура']=$КоньБел[2]
$Доска['G',1,'Цвет']='Черный'
$Доска['H',1,'Фигура']=$ЛадьяБел[2]
$Доска['H',1,'Цвет']='Белый'
....
$Доска['A',8,'Фигура']=$ЛадьяЧерн[1]
$Доска['A',8,'Цвет']='Белый'
$Доска['B',8,'Фигура']=$КоньЧерн[1]
$Доска['B',8,'Цвет']='Черный'
$Доска['С',8,'Фигура']=$СлонЧерн['Белый']
$Доска['C',8,'Цвет']='Белый'
$Доска['D',8,'Фигура']=$ФерзьЧерн
$Доска['D',8,'Цвет']='Черный'
$Доска['E',8,'Фигура']=$КорольЧерн
$Доска['E',8,'Цвет']='Белый'
$Доска['F',8,'Фигура']=$СлонЧерн['Черный']
$Доска['F',8,'Цвет']='Черный'
$Доска['G',8,'Фигура']=$КоньЧерн[2]
$Доска['G',8,'Цвет']='Белый'
$Доска['H',8,'Фигура']=$ЛадьяЧерн[2]
$Доска['H',8,'Цвет']='Черный'
Лично я стараюсь не использовать многомереки без необходимости. А разбиваю их на понятные одномерные, так проще воспринимать код.
Но, например, если некий предмет способен “переезжать” с локации на локацию и в пределах локации менять свое положение и оставаться там, пока кто-то не переместит его на другую, то в таких случаях можно хранить положение предмета в двумерном массиве.
Опять таки, надо понимать, что и как хранить. Мне проще хранить местонахождение предмета в свойствах самого предмета, или через динамический массив, где индекс массива - код предмета, а значение - локация. При больших массивах данных я привык пользоваться индексами. Каждый предмет, локация, непись (при необходимости) имеет свой уникальный индекс и через этот индекс они связываются.
Обычно я делаю функции-прокладки, которые могут из общего массива данных найти нужное и в любом количестве. Например для “Снаряжения” - по ID “Владельца” найти все Снаряжение, которое принадлежит данному Владельцу.
Доброго времени суток. Такой странный вопрос по предметам, а конкретно по $SELOBJ… Есть ли возможность выделить предметом кодом, через тот же act к примеру, без прямого клика игроком на предмет в инвентаре, чтобы выделить этот самый предмет?
И макро вопрос, как проверить есть ли предмет в инвентаре, а то я что-то в документации не могу найти енто самое.
n3m0,
Чесслово, тут надо дождаться гуру. Реально, не сильно в теме.
Я попробовал пользоваться стандартным набором инвентаря и понял, что он меня совершенно не устраивает. По сути он пустой, оболочка - не более. Можно добавить-убрать и по сути всё. Ни количества, ни других свойств. И я решил, что если все свойства надо хранить отдельно - то нахрена использовать? Я написал свой, сначала было кривовато, но терпимо (Старый пример лежит несколько страниц назад. https://qsp.org/forum/23-kak-sdelat?page=425). А теперь можно применять к любому количеству “предметов” с совершенно разными “внутренними структурами”.
Как проверить, есть ли среди предметов предмет, содержащий такое-то слово — я вот таким кодом пользуюсь:
i=1
yes_its_here=0
:ii
$currentObjectName=$getObj(i)
if instr($currentObjectName,$findname):
yes_its_here=1
end
if i < countObj or i = countObj:
i+=1
jump'ii'
end
n3m0, событие выделения предмета, согласно вики, только по клику мышью. Какая задача стоит? Возможно, можно решить другим способом.
