Функции deactivate в скриптовом языке ТЕС не существует, так что название темы - шутка (я решил назвать по аналогии с темой Скрипт с disable, созданной Deska). Есть пара функций enable-disable, отвечающая за включение-выключение присутствия объекта в игровом мире. Функция же activate тоже отвечает за включение, но другого рода - активацию, действие, выполняемое с объектом. Почему бы и ей не иметь своего антипода deactivate, деактивировать (я иногда путаю и пишу deactivate вместо disable). Если это дверь, контейнер или книга, то при клике на них они откроются, все остальные предметы помещается в инвентарь - все это работа функции activate.
То есть момент помещения в инвентарь можно определить точно (для этого в скрипте вызываем условие onActivate == 1, внутри ставим нужной переменной нужное значение и функцию Activate). А момент выкладывания? Вот тут-то нам и поможет функция deactivate. Ну на самом деле такой функции нет)), так что мы сымитируем те действия, которые она должна выполнять, а именно определять момент выкладывания предмета из инвентаря (поскольку само выкладывание производим мы сами). Для этого необходимо прежде всего определить, что конкретный объект находится в инвентаре. Если копия объекта одна, то нет проблем ( Player -> GetItemCount, название == 1 ), а если копий несколько? Можно локальной переменной в скрипте каждой копии объекта присвоить свое уникальное значение, а можно поступить еще проще. Определить любую координату объекта (например, для координаты х это GetPos, x). Если объект находится в инвентаре, то любая его координата равна нулю. Однако тут следует иметь ввиду, что координата объекта, находящегося не в инвентаре (скажем так, в мире) на самом деле может быть равна нулю. В этом случае можно поставить проверку условия сразу на две координаты, что еще более уменьшит и без того малую вероятность совпадения координат, а еще лучше на все три - тогда в мире будет существовать всего лишь одна-единственная точка, начало координат, где координаты предмета в мире будут равны координатам объекта в инвентаре. В эту точку можно поставить камень, колонну, бочку - в общем любой неподвижный объект и перекрыть игроку доступ туда, или сделать локацию "в обход".
Теперь, когда мы знаем, что предмет в инвентаре, можно обнаружить и момент выкладывания из инвентаря. Значение локальной переменной в скрипте объекта постоянно проверяется и когда при старом значении обнаруживается изменение координат с нуля на число, то значит предмет был выложен. Вот примерный скрипт:
begin scr_deactivate
short varBag
if ( varBag == 0 );предмет в мире
if ( GetPos, x == 0 )
if ( GetPos, y == 0 )
if ( GetPos, z == 0 )
set varBag to 1
endif
endif
endif
else;предмет в инвентаре
if ( GetPos, x != 0 )
if ( GetPos, y != 0 )
if ( GetPos, z != 0 )
MessageBox "Предмет выложен"
set varBag to 0
endif
endif
endif
endif
end
Этот скрипт запаздывает на 1 кадр, поскольку мы обнаруживаем "неладное" тогда, когда предмет уже имеет новые координаты, а значит был выложен. Однако момент взятия можно не упустить - переменной varBag можно присваивать значение 1, когда вызывается функция Activate
if ( onActivate == 1 )
set varBag to 1
Activate
endif
но по скорости выполнения это хуже, так как в этом случае будет проверяться сразу два условия (второе, что varBag == 1 ), а не одно, как в верхнем скрипте, к тому же скрипт теряет свою красивую симметрию...
Похожий принцип будет у скрипта, обнаруживающего момент выхода из режима меню (что может быть также полезно в некоторых случаях).
begin scr_menu_out
short varMenu
if ( MenuMode == 1 )
if ( varMenu == 1 )
return
else
set varMenu to 1
endif
else
if ( varMenu == 0 )
return
else
MessageBox "Вы вышли из меню"
set varMenu to 0
endif
endif
end