RU 📌 Pinned

Как сделать?

Dark[Ol(U23)leneri] #34 18.04.2010 22:57 6408 comments 2432039 views

А чем такой код не нравится?

IF SELOBJ = 'Скафандр': 
    if item_on = 0: $menu[0] = 'Одеть:item.acts' else $menu[0] = 'Cнять:item.acts' 
    $menu[1] = 'Выбросить:item.acts' 
    $menu[2] = 'Положить:item.acts' 
END 
IF SELOBJ = '....':
    $menu[0] = ...
END
menu '$menu' 
unsel
Aleks Versus Moderator 30.09.2014 12:07 (11 years ago)

Jolly Roger,
в качестве параметра команде menu передаётся название массива, в котором лежат пункты меню. То, что ты там передаёшь ему, работает по чистой случайности и совпадению. Если пункты меню помещаешь в массив $menu_item[], то команда вызова меню:

menu '$menu_item'

Если пункты меню помещаешь в массив $скафандр, то команда вызова меню:

menu '$скафандр'

То есть для безглючной работы команд меню для каждого предмета надо создавать свой массив команд меню и свою локацию- обработчик?

Aleks Versus Moderator 30.09.2014 14:24 (11 years ago)

Jolly Roger,
нет, зачем. У меня предметы типизированы. Т.е. скажем у предмета “яблоко” есть свойство - тип “еда”. На локации-обработчике выделения предмета проверяется свойство предмета. Если тип “еда”, в массив $menu_object[] добавляется пункт
“съесть:object.eat”. И так в зависимости от свойств предмета, его состояния пункт меню добавляются в массив. Яблоко может быть не только едой, но скажем ингредиентом, снарядом и пр. Все действия с типовыми объектами ничем не отличаются. “Надеть куртку” ничем не отличается от “надеть скафандр”, поэтому и для скафандра и для куртки будет создаваться одинаковый пункт меню с отсылкой на одну и ту же локацию-обработчик пункта меню

$menu_object[]='Надеть:object.onBody'

И в самом конце локации-обработчика выбора предмета:

menu '$menu_object'

То есть получается примерно так:
(локация ‘ONOBJSEL’)
IF SELOBJ = ‘яблоко’:
potion = 32
if item_on = 0: $menu_object[0] = ‘Взять:object.eat’ else $menu_object[0] = ‘Положить:object.eat’
if $potion_type[potion] = ‘food’:$menu_object[1] = ‘Съесть:object.eat’ else $menu_object[1] = ‘Выпить:object.eat’
$menu_object[2] = ‘Выбросить:object.eat’
END

IF SELOBJ = ‘жидкость’:
potion = 101
if item_on = 0: $menu_object[0] = ‘Взять:object.eat’ else $menu_object[0] = ‘Положить:object.eat’
if $potion_type[potion] = ‘food’:$menu_object[1] = ‘Съесть:object.eat’ else $menu_object[1] = ‘Выпить:object.eat’
$menu_object[2] = ‘Выбросить:object.eat’
END

menu ‘$menu_object’

И так на каждый объект.
Верно?

Aleks Versus Moderator 30.09.2014 16:43 (11 years ago)

Верно, но зачем повторять один и тот же код? Я не знаю, как у тебя организованы предметы, поэтому покажу, как у меня.
В грубом приближении в окне инвентаря выводятся вот такие предметы:

яблоко<oid:0:oid>
меч<oid:1:oid>
элликсир<oid:2:oid>

в угловых скобках находится идентификатор объекта. Для наглядности сделал число. Он визуально скрыт от игрока, поскольку usehtml = 1, html-рендерер воспринимает его как тег, но поскольку это несуществующий тег, он не обрабатывается, а только скрывается.
Сам предмет представляет собой запись типа:

$object_name[0]='Яблоко'
$object_type[0]='еда, ингредиент, снаряд,'
object_kolvo[0]=3
...и т.д.

На локации $onobjsel:

! получаем идентификатор. Проще использовать регэксп, но если не знакомо:
oid = val(mid($selobj,instr ($selobj,"<oid:")+5,len($selobj)-instr($selobj,':oid>')+5))
! собираем меню:
if instr($object_type[oid],'еда')<>0:
     if  instr($object_type[oid],'жидкость')<>0: $glagol='Выпить' else $glagol='Съесть'
     $object_menu[]=$glagol+':object.eat'
end
if instr($object_type[oid],'ингредиент')<>0: $object_menu[]='использовать в приготовлении зелья:object.addInPoison'
if instr($object_type[oid],'снаряд')<>0: $object_menu[]='швырнуть:object.killthemall'
if instr($object_type[oid],'одежда')<>0:
     if $activing_object[oid]='onBody': $object_menu[]='Снять:object.remove'
     if $activing_object[oid]='inBag':  $object_menu[]='Одеть:object.onBody'
end
menu '$object_menu'
unselect

Как-то так.

newsash, Aleks Versus, спасибо за помощь. Нечто подобное мне и хотелось замутить, но не знал подобных тонкостей. Хотя у меня раньше все было проще, вот так:
IF $SELOBJ = ‘меч’:
UNSEL
GS ‘Sword’
END
Все работало, но захотелось апгрейда…
Лучшее - враг хорошего.

Aleks Versus, вот мой код:

Spoiler

локация ‘START’
код на ней:
GS ‘POTIONS’
$activing_object[32]=‘inBag’
$activing_object[101]=‘inBag’

локация ‘POTIONS’ (массив предметов, загружается на стартовой локации)
код на ней:
$object_type[32]=‘fluid, reagent, missile, ’
$potion_type[32] = ‘fluid’
$potion_name[32] = ‘вода’
$potion_descr[32] = ‘вода из реки’

$object_type[101]=‘food, reagent, missile, outfit,’
$potion_type[101] = ‘food’
$potion_name[101] = ‘хлеб’
$potion_descr[101] = ‘хлеб черный’

локация ‘ONNEWLOC’
код на ней:
ADDOBJ ‘водаoid:32:oid
ADDOBJ ‘хлебoid:101:oid

локация ‘ONOBJSEL’
код на ней:
IF SELOBJ = ‘водаoid:32:oid’:
!oid = 32
END
IF SELOBJ = ‘хлебoid:101:oid’:
!oid = 101
END
! получаем идентификатор.
oid = val(mid($selobj,instr ($selobj,”oid:")+5,len($selobj)-instr($selobj,':oid’)+5))
! собираем меню:
if instr($object_type[oid],’food’)<>0:
if instr($object_type[oid],’fluid’)<>0: $verb =‘Выпить’ else $verb=‘Съесть’
$object_menu[0]=$verb+’:object.eat’
end
if instr($object_type[oid],’reagent’)<>0: $object_menu[1]=‘Смешать:object.addInPoison’
if instr($object_type[oid],’missile’)<>0: $object_menu[2]=‘Метнуть:object.killthemall’
if instr($object_type[oid],’outfit’)<>0:
!if $activing_object[oid]=‘inBag’: $object_menu[3] = ‘Одеть:object.remove’ else $object_menu[3] = ‘Снять:object.remove’
if $activing_object[oid]=‘inBag’: $object_menu[3]=‘Одеть:object.dressing’
if $activing_object[oid]=‘on’: $object_menu[3]=‘Снять:object.dressing’
end
menu ‘$object_menu’
unselect

При этом пункты меню у предметов не появляются, но если снять ! с oid = 32, oid = 101, то пункты меню появляются и команды выполняются, хотя и глючно, напр. пункт “снять” появляется у воды, где его быть не должно.
То есть:
1) строка
! получаем идентификатор.
oid = val(mid($selobj,instr ($selobj,”oid:")+5,len($selobj)-instr($selobj,':oid’)+5))
не работает.
2) В чем моя ошибка?

в mid последним параметром надо передавать длину вырезаемой строки, а не позицию
т.е надо

oid = val(mid($selobj,instr ($selobj,"<oid:")+5, instr($selobj,':oid>') - instr ($selobj,"<oid:")-5))

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

oid = val($strfind($selobj, '<oid:(.*?):oid>$', 1))

Всем здраститя!
Поделитесь советом. Как в AEROShell сделать так, чтоб при просмотре предмета по средством VIEW, всплывало окошко с заданными параметрами VIEW_X = 650; VIEW_Y = 400.
Но при закрытии его, все возвращалось к стандарту до VIEW_X = 450; VIEW_Y = 300.
ОЧЕНЬ ПРОШУ, ВСЮ ГОЛОВУ СЛОМАЛ УЖЕ!

Podkovally,
никак. “Закрытие VIEW” невозможно обработать.

Может есть какой-нибудь обходной вариант?
Чтоб при нажатии на предмет, его можно было хорошенько так рассмотреть =)

Обходной путь - выставлять параметры перед каждым вызовом VIEW.

newsash,
Скорее перед всеми остальными действиями, так как параметр выставляется общий на всю игру :-)
Ладно, если ничего не придумаю, создам отдельную локацию для предмета типа “внимательно рассмотреть” и действие “убрать в рюкзак” и в gt то и впихну параметры по-умолчанию!

Podkovally:

Скорее перед всеми остальными действиями,

Мне кажется самым простым всё-таки перед каждым вызовом view.

view 'something'
!заменяется на 
gs 'view', 'something', 'инвентарь'

Локация ‘view’:

if $args[1] = 'инвентарь':
  VIEW_X=100
  VIEW_Y=100
else:
  VIEW_X=200
  VIEW_Y=200
end

view $args[0]

P.S. А вообще Аэрой уже мало кто пользуется, вместо неё теперь Навигатор.

Log in or Register to post comments.