fallout.ru

Новые функции, появившиеся в Трибунале

Трибунал, официальное дополнение к стандартной игре, добавляет множество новых функций и возможностей. Помимо этого он содержит исправления и добавления к старым функциям. Однако запомните, что, если Вы создаёте мод на основе Трибунала, пользователь тоже должен иметь это дополнение!

Заметьте: все эти функции и исправления были также включены в Бладмун, второе официальное дополнение. То есть все скрипты созданные на основе Трибунала пойдут и без него при условии наличия Бладмуна.

Исправления и изменения

  • Теперь функция “SetPos” принимает в качестве аргументов переменные типа float.
  • SetAngle” отныне также принимает в качестве аргументов переменные типа float
  • Исправлено действие функции “Equip”, благодаря которой можно одевать на персонажей одежду и броню.
  • Функция “AIActivate” была исправлена

Список новых функций

GetPCSneakingForceJump
GetPCRunningClearForceJump
GetPCJumpingGetForceJump
GetScaleForceMoveJump
SetScaleClearForceMoveJump
ModScaleGetForceMoveJump
GetWaterLevelGetCollidingPC
SetWaterLevelGetCollidingActor
ModWaterLevelHurtCollidingActor
EnableLevitationAddToLevCreature
DisableLevitationAddToLevItem
PlaceItemRemoveFromLevCreature
GetWeaponTypeRemoveFromLevItem
GetArmorTypeGetSquareRoot
HasItemEquippedExplodeSpell
ForceRunSetDelete
ClearForceRunGetWeaponDrawn
GetForceRunGetSpellReadied

Разрешение на обмен вещами

Short companion
Set companion == 1

Трибунал предлагает нам новую возможность обмениваться вещами с NPC и существами. Чтобы включить её Вам необходимо в скрипте соответствующего персонажа объявить локальную переменную “companion” и присвоить ей значение 1. 0 – как не трудно догадаться, отключает подобную возможность. Этот метод используется как для наёмников, так и для вьючных животных.

Float minimumprofit

Похоже, это ещё одна переменная, устанавливаемая игрой. Возможно, она определяет разницу между текущей стоимостью всех вещей персонажа и начальной. Один из вариантов её использования: если игрок что-то забирает у наёмника (то есть переменная принимает отрицательное значение) и тот остаётся в убытке, тогда он покидает игрока раз и навсегда.

Пример: скрипт, прикреплённый к наёмнику Калвусу, который покидает игрока или потому что истекает контракт, или потому что последний что-то у него забрал.

if ( GetJournalIndex Merc_Calvus_Quit < 1 ) ;если Калвус уже покинул игрока, не повторять
            if ( Contract_Calvus == 1 ) ;если у Калвуса нет контракта, не делать
                        if ( minimumProfit < 0 ) ;Калвус покидает игрока за то, что последний забрал его вещи
                                    AiWander 128 6 0 40 30 20 0 0 0 0 0 0
                                    Set Companion to 0; stop sharing
                                    StopScript Contract_Calvus
                                    Set Contract_Calvus to 0
                                    ForceGreeting
                                    return
                        else
                                    if ( Contract_Calvus == 0 ) ;управляет Калвусом, когда контракт истекает
                                                AiWander 128 6 0 40 30 20 0 0 0 0 0 0
                                                Set Companion to 0; stop sharing
                                                if ( GetJournalIndex Merc_Calvus < 10 )
                                                            Journal Merc_Calvus 10 ;первый контракт истёк
                                                else
                                                            Journal Merc_Calvus 20 ;самый последний контракт истёк
                                                endif
                                    endif
                        endif
            endif
endif

short StayOutside
set StayOutside to 1

Очень полезная переменная, которая при получении значения 1 позволяет оставить компаньона снаружи, когда игрок входит в помещение, и вновь присоединиться, когда он из него выходит.

Функции, определяющие действия игрока

GetPCSneaking (возвращает short) ;игрок крадётся
GetPCRunning (возвращает short) ;игрок бежит
GetPCJumping (возвращает short) ;игрок прыгает

Эти функции возвращают 1, если игрок совершает соответствующее действие.

Пример: когда игрок держит в руках ножницы, он получает предупреждающие его об опасности сообщения, зависящие от конкретных действий.

Begin momscript

short warn

if ( player->HasItemEquipped "scissors" )
            if ( warn != 1 )
                        if ( GetPCRunning )
                                    MessageBox "Не беги с ножницами!"
                                    set warn to 1
                        endif
            endif
            if ( warn != 2 )
                        if ( GetPCJumping )
                                    MessageBox "Не прыгай с ножницами! Ты выколешь себе глаз!"
                                    set warn to 2
                        endif
            endif
            if ( warn != 3 )
                        if ( GetPCSneaking )
                                    MessageBox "Ты не спрячешь от меня эти ножницы!"
                                    set warn to 3
                        endif
            endif
else
            set warn to 0
endif

end

Размеры объектов

GetScale (возвращает float)
SetScale НовыйРазмер_float
ModScale ИзменениеРазмера_float

If (doonce == 0 )
            SetScale 0.1
            Set doonce to 1
endif

Эти функции предназначены для определения или установления размеров объекта. Вы можете ставить значения от 0 до 10, то есть вне пределов, установленных Bethesda (от 0.5 до 2), что и продемонстрировано в примере сверху.

Вам не следует вызывать функцию SetScale постоянно – это может привести к зависанию игры. Также не следует использовать её вместе с одноразовой конструкцией, ведь при загрузке размеры вновь возвращаются в пределы 0,5 – 2.0. Выходом может послужить использование этой функции через определённый промежуток времени (например, каждые 10 фреймов). Более рациональным представляется способ вставить функцию в главный скрипт Бладмуна или Трибунала, который выполняется при каждом запуске игры.

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

Begin scalescript

short questionAsked
short button
float direction
float currscale
float tempscale

if ( MenuMode )
            return
endif

if ( OnActivate == 1 )
            if ( questionAsked == 0 )
                        MessageBox, "Как вы хотите изменить размеры этого объекта?" "Увеличить" "Уменьшить"
                        set questionAsked to 1
            endif
endif

if ( questionAsked == 1 )
            set button to GetButtonPressed
            if ( button == -1 )
            else
                        if ( button == 0 )
                                    set direction to 1
                        elseif ( button == 1 )
                                    set direction to –1
                        endif
                        set questionAsked to 0
                        set button to 0
            endif
endif

if ( direction != 0 )
            set tempscale to .3 * GetSecondsPassed
            set tempscale to tempscale * direction
            ModScale tempscale
            set currscale to GetScale
            if ( direction == -1 )
                        if ( currscale <= .5 )
                                    set direction to 0
                        endif
            else
                        if ( currscale >= 2 )
                                    set direction to 0
                        endif
            endif
endif

end scalescript

Уровень воды

GetWaterLevel (возвращает float)
SetWaterLevel НовыйУровень_float
ModWaterLevel ИзменениеУровня_float

Прекрасная возможность создавать ужасные ловушки! Первая функция возвращает высоту уровня воды в текущем интерьере. А последние две его изменяют соответствующим образом.

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

Begin crank

short changelevel
float direction
float waterlift
short crankturn
short currcrank
float newwaterlevel

if ( MenuMode )
            return
endif

if ( OnActivate == 1 )
            if ( changelevel == 0 )
                        if ( direction == 1 )
                                    set direction to –1
                        else
                                    set direction to 1
                        endif
                        set changelevel to 1
            endif
endif

if ( changelevel == 0 )
            return
endif

set crankturn to 360 * GetSecondsPassed
set crankturn to crankturn * direction
set currcrank to GetAngle X
set crankturn to currcrank + crankturn
SetAngle X crankturn
set waterlift to 120 * GetSecondsPassed
set waterlift to waterlift * direction
ModWaterLevel waterlift
set newwaterlevel to GetWaterLevel

if ( direction == 1 )
            if ( newwaterlevel >= 600 )
                        SetWaterLevel 600
                        set changelevel to 0
            endif
else
            if ( newwaterlevel <= 0 )
                        SetWaterLevel 0
                        set changelevel to 0
            endif
endif

end crank

Этот скрипт является изменённой версией скрипта “Float”, которая заставляет ящики качаться на поверхности воды не зависимо от её уровня. Также теперь они будут качаться, когда на них встанет игрок.

Begin NewFloat

float timer
float swingTime
float startAngle
float currangle
short reset
float xvalue
float zvalue
float zoffset
float tmpoffset
float weightoffset

set startAngle to GetStartingAngle, x

if ( MenuMode == 0 )
            if ( timer == 0 )
                        if ( reset == 0 )
                                    set timer to Random 100
                                    set timer to timer / 4
                        endif
            endif

            set swingTime to 1
            set timer to ( timer + GetSecondsPassed )
            set currangle to GetAngle X
            set xvalue to 10 * GetSecondsPassed
            set zvalue to 5 * GetSecondsPassed

            if ( GetStandingPC )
                        set zoffset to –30
                        SetAngle X 0
            else

                        ;поворот наверх

                        if ( timer < swingTime )
                                    set currangle to currangle + xvalue
                                    SetAngle X currangle
                                    set zoffset to zoffset + zvalue

                        ;поворот вниз

                        elseif ( timer < (swingTime * 3) )
                                    set currangle to currangle – xvalue
                                    SetAngle X currangle
                                    set zoffset to zoffset – zvalue

                        ;опять вверх

                        elseif (timer < (swingTime * 4 ) )
                                    set currangle to currangle + xvalue
                                    SetAngle X currangle
                                    set zoffset to zoffset + zvalue

                        ;сброс таймера на 0

                        else
                                    set timer to 0
                                    set reset to 1
                                    set zoffset to 0
                                    SetAngle, x, startangle
                        endif
            endif

            set tmpoffset to GetWaterLevel
            set tmpoffset to tmpoffset + zoffset
            SetPos Z tmpoffset
endif

end NewFloat

Левитация

EnableLevitation
DisableLevitation

Функции разрешают левитацию и отменяют её соответственно. Когда вызывается “DisableLevitation” все текущие эффекты полёта снимаются. Когда же игрок в этом случае вновь пытается скастовать заклинание левитации, ему выводится сообщение, хранящееся в переменной “sLevitateDisabled”.

Пример: скрипт, прикрепляемый к камню, запрещающему левитацию в конкретной комнате.

Begin clampstone

short turnedoff
short gavemessage

if ( turnedoff == 0 )
            DisableLevitation
            if ( gavemessage == 0 )
                        set gavemessage to 1
                        MessageBox "Странный камень на потолке комнаты не позволяет использовать левитацию."
            Endif
else
            EnableLevitation
            if ( gavemessage == 1 )
                        set gavemessage to 0
                        MessageBox "Странный камень был выключен, теперь вы можете летать в этой комнате."
            Endif
endif

if ( OnActivate == 1 )
            if ( turnedoff == 0 )
                        set turnedoff to 1
            else
                        set turnedoff to 0
            endif
endif

end

А этот скрипт прикрепляется к двери, ведущий из этой комнаты:

Begin enable_lev_on_exit

if ( OnActivate == 1 )
            MessageBox "Вы выходите за пределы сферы влияния камня..."
            EnableLevitation
            Activate
endif

end

Создание объекта

PlaceItem "ID объекта", float_пер_X, float_пер_Y, float_пер_Z, float_пер_ПоворотПоZ
PlaceItemCell "ID объекта", "ID локации", float_пер_X, float_пер_Y, float_пер_Z, float_пер_ПоворотПоZ

Эта функции позволяют создать новую копию объекта в нужном месте. Позволяется задать конкретные координаты и угол поворота по оси z. В качестве аргументов допускаются местные переменные типа float. Вторая функция позволяет также задать, в какой локации должен появиться объект. Довольно удобная функция, позволяющая Вам добавлять предметы без предварительного их размещения в редакторе.

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

Пример: при активации предмета задаётся вопрос о том, какой объект и где необходимо создать. Если выбран горшок, он создаётся в той же комнате, что и активатор, а если ключ – в локации “key room”.

Begin makethingsimple

short questionAsked
short button
float myX
float myY
float myZ

if ( MenuMode )
            return
endif

if ( OnActivate == 1 )
            if ( questionAsked == 0 )
                        MessageBox, "Создать новый..." "...горшок" "...ключ"
                        set questionAsked to 1
                        set myX to GetPos X
                        set myY to GetPos Y
                        set myZ to GetPos Z + 100
            endif
endif

if ( questionAsked != 0 )
            if ( questionAsked == 1 )
                        set button to GetButtonPressed
                        if ( button == -1 )
                        else
                                    if ( button == 0 )
                                                PlaceItem "Misc_pot_redware_01" myX myY myZ 45
                                    elseif ( button == 1 )
                                                PlaceItemCell "misc key" "key room" myX myY myZ 45
                                    endif
                                    set questionAsked to 0
                                    set button to –1
                        endif
            endif
endif

end

Информация о надетом объекте

GetWeaponType (возвращает short)
GetArmorType часть_числ (возвращает short)
HasItemEquipped "ID предмета" (возвращает short)

Эти функции вызываются для того, чтобы проверить, что надето на персонажа. Первая функция возвращает тип оружия, которое он держит (смотрите таблицу 1.1). Вторая – возвращает тип (Таблица 1.3) того предмета брони (в зависимости от индекса – таблица 1.2), который в данный момент надет на персонажа. Функция HasItemEquipped возвращает 1, если необходимый предмет надет.

Типы оружия (таблица 1.1)

Имя типа оружияИндекс типа
Безоружный
-1
Одноручный клинок
0
Одноручный меч
1
Двуручный меч ближней дистанции
2
Одноручное дробящее
3
Двуручное дробящее ближней дистанции
4
Двуручное дробящее средней дистанции
5
Двуручное копьё средней дистанции
6
Одноручный топор
7
Двуручный топор средней дистанции
8
Лук
9
Арбалет
10
Метательное
11
Стрела лука
12
Стрела арбалета
13

Части брони (таблица 1.2)

Имя части брониИндекс части
Шлем
0
Кираса
1
Левый наплечник
2
Правый наплечник
3
Штаны
4
Ботинки
5
Левая перчатка
6
Правая перчатка
7
Щит
8
Левый браслет
9
Правый браслет
10

Тип брони (таблица 1.3)

Имя типа броняИндекс типа
Без доспехов
-1
Лёгкая броня
0
Средняя броня
1
Тяжёлые доспехи
2

Пример: когда скрипт прикреплён к объекту, его копию наносит урон ему в зависимости от брони и оружия игрока. Если в руках игрока оружие “Rock Splitter”, камень взрывается с первого удара. При этом он посылает осколки прямо в лицо игрока, если у него нет шлема или щита.

Begin breakme

float hitsleft
float hitpercent
short damage
short tempdamage
short weapon
short doOnce
short shieldType
short hasHammer
short hitRock

if ( doOnce == 0 )
            set hitsleft to 10000
            set doOnce to 1
endif

if ( OnActivate )
            set hasHammer to ( player->HasItemEquipped "RockSplitter" )
            if ( hasHammer == 1 )
                        MessageBox "Дробитель камней высвобождает свою невероятную мощь..."
                        set hitsLeft to 0
            else
                        MessageBox "Вы бьёте камень, ..."
                        set weapon to ( player->GetWeaponType )
                        set damage to ( player->getstrength )
                        set tempdamage to 5

                        if ( weapon == -1 )
                                    set tempdamage to 1
                        endif

                        if ( weapon >= 9 )
                                    set tempdamage to 2
                        endif

                        if ( weapon == 4 )
                                    set tempdamage to 10
                        endif

                        if ( weapon == 8 )
                                    set tempdamage to 8
                        endif

                        set damage to damage * tempdamage
                        set hitsleft to hitsleft – damage
            endif

            if ( hitsleft <= 0 )
                        disable
                        set shieldType to ( player->GetArmorType 8 )
                        if ( shieldType == -1 )
                                    set shieldType to ( player->GetArmorType 0 )
                                    if ( shieldType == -1 )
                                                MessageBox "...и он разваливается, посылая смертельные осколки прямо Вам в глаза."
                                                Player->ModHealth –50
                                    else
                                                MessageBox "...и он разваливается, смертельные осколки отскакивают от Вашего шлема."
                                    Endif
                        else
                                    MessageBox "...и он разваливается, смертельные осколки отскакивают от Вашего щита."
                        Endif
            else
                        set hitpercent to hitsleft / 100
                        set hitpercent to 100 – hitpercent
                        MessageBox "...и он повреждён на %.2f пунктов, однако всё ещё цел.", hitpercent
            endif
endif

End

Функции движения NPC

ForceRun
ClearForceRun
GetForceRun (возвращает short)

ForceJump
ClearForceJump
GetForceJump (возвращает short)

ForceMoveJump
ClearForceMoveJump
GetForceMoveJump (возвращает short)

Все эти функции управляют специальными движениями неигровых персонажей. Функция ForceRun заставляет NPC бежать, ForceJump – постоянно прыгать, ForceMoveJump – прыгать только во время движения. Каждая третья функция возвращает 1, если производится необходимое движение. Все функции, начинающиеся с “Clear…”, используются для выключения соответствующего режима. Учтите, что NPC может выполнять лишь одно движение в отдельный участок времени. Приоритет подобных действий выглядит следующим образом: Красться > Бежать > Прыгать Всегда > Прыгать Во Время Движения.

Пример: этот скрипт устанавливает способ передвижения Атлету, который будет по стадиону бесконечно.

Begin AthleteControl

short questionAsked
short button
short isrunning
short isjumping

if ( MenuMode )
            return
endif

if ( OnActivate == 1 )
            set isrunning to ( Athlete->GetForceRun )
            set isjumping to ( Athlete->GetForceMoveJump )
            if ( questionAsked == 0 )
                        if ( isrunning )
                                    MessageBox, "Пускай Атлет не будет бежать?" "Да" "Нет"
                        else
                                    MessageBox, "Пускай Атлет бежит?" "Да" "Нет"
                        endif

                        set questionAsked to 1

            endif
endif

if ( questionAsked == 1 )
            set button to GetButtonPressed
            if ( button == -1 )
            else
                        if ( isrunning == 0 )
                                    if ( button == 0 )
                                                Athlete->ClearForceMoveJump
                                                Athlete->ForceRun
                                    endif
                        else
                                    if ( button == 0 )
                                                Athlete->ClearForceRun
                                    endif
                        endif
                        if ( isjumping )
                                    MessageBox, "Пускай Атлет не будет прыгать?" "Да" "Нет"
                        else
                                    MessageBox, "Пускай Атлет прыгает?" "Да" "Нет"
                        endif

                        set questionAsked to 2
                        set button to –1

            endif
endif

if ( questionAsked == 2 )
            set button to GetButtonPressed
            if ( button == -1 )
            else
                        if ( isjumping == 0 )
                                    if ( button == 0 )
                                                Athlete->ClearForceRun
                                                Athlete->ForceMoveJump
                                    endif
                        else
                                    if ( button == 0 )
                                                Athlete->ClearForceMoveJump
                                    endif
                        endif
                        set questionAsked to 0
                        set button to –1
            endif
endif

end

Функции прикасающегося объекта

GetCollidingPC (возвращает short)
GetCollidingActor (возвращает short)

if ( GetCollidingPC == 1 )

HurtCollidingActor Урон

HurtCollidingActor 100

Эти функции прикрепляются к объекту, чтобы обеспечить его взаимодействие с персонажами. GetCollidingPC возвращает 1, если игрок соприкасается с объектом. GetCollidingActor работает также, но только для NPC. Последняя функция наносит персонажу определённый урон каждую секунду, пока тот соприкасается с опасным объектом.

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

Begin hurtactor

if ( GetCollidingPC == 1 )
            MessageBox "Вы ревёте от боли, которая исходит от камня, к которому Вы прикоснулись."
Elseif ( GetCollidingActor == 1 )
            MessageBox "Поблизости кто-то ревёт от боли."
Endif

HurtCollidingActor 100

End

Уровневые функции

AddToLevCreature “имя уровневого существа” “существо” уровень_числ
AddToLevItem “имя уровневого предмета” “предмет” уровень
RemoveFromLevCreature “имя уровневого существа” “существо” уровень_числ
RemoveFromLevItem “имя уровневого предмета” “предмет” уровень

Эти функции необходимы для управления списком уровневых объектов во время игры, который определяет какой объект может встретить игрок на его текущем уровне развития. Первые две функции добавляют в список необходимые элементы, последние две – убирают. Если во время удаления в качестве аргумента уровень задать «-1», то все элементы, содержащие указанный объект будут удалены.

Учтите: функции удаления не уничтожают существующие предметы, которые уже были рассчитаны, как определённые существа. Однако, это позволяет избежать повторного расчёта подобным образом. То есть больше такое создание из уровневых объектов получиться не может.

Пример: при активации объекта, к которому будет прикреплён этот скрипт, будет меняться количество крыс. Если ещё не было никаких изменений – все крысы и их мясо пропадут из списка. В противном случае – вновь в нём появятся.

Begin norats

short norats

if ( OnActivate == 1 )
            if ( norats == 0 )
                        set norats to 1
                        RemoveFromLevCreature "rat_scamp_crab" "rat" –1
                        RemoveFromLevCreature "rat_scamp_crab" "rat-fast" –1
                        RemoveFromLevItem "lev_meat" "rat_meat" –1
                        MessageBox "Больше крыс не будет."
            Else
                        set norats to 0
                        AddToLevCreature "rat_scamp_crab" "rat" 1
                        AddToLevCreature "rat_scamp_crab" "rat-fast" 1
                        AddToLevItem "lev_meat" "rat_meat" 1
                        MessageBox "Крысы вернулись."
            Endif
endif

end

Разнообразные функции

Квадратный корень

GetSquareRoot, число (возвращает float)

set var_1 to GetSquareRoot var_2

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

Взрыв

ExplodeSpell “ID заклинания”

ExplodeSpell "proj_trap_spell"

Функция создаёт копию заклинания, действующую на расстоянии прикосновения относительно себя. Если при этом также используется эффект дальности действия, то получается нечто вроде «взрыва».

Полное удаление копии

SetDelete flag (где flag – числовое значение)

Функция может использоваться вкупе с Disable для более полного удаления объекта. “SetDelete 1” помечает копию, как удалённую. “SetDelete 0” – убирает эту метку. Это довольно полезно для оптимизации. Многие скрипты объектов содержат функция Disable. Благодаря ней, как только игрок берёт этот предмет, эта его копия деактивируется, а в инвентарь добавляется уже новая. Подобный процесс забирает оперативную память и быстродействие процессора, поскольку каждый фрейм выполняются скрипты даже деактивированных объектов. Если же копия помечена, как удалённая, то она, в принципе, пропадает. Учтите, что, если она была создана в плагине, то она так там и остаётся, хоть и «знает», что не должна – ведь у неё нет ни анимации, ни скрипта. Если же копия была создана во время игры, то она удаляется раз и навсегда.

Также запомните, что нельзя использовать эту функцию сразу же после деактивации объекта – игра просто вылетит! Поэтому подождите некоторое время, прежде чем помечать объект удалённым. Так что можно поместить нечто вроде этого в начало Вашего скрипта:

if ( deleteobj == 1 ) ;местная переменная, которой вы присваиваете 1, когда хотите удалить объект
            if ( deletetimer == 0 )
                        Disable
            endif

            if ( deletetimer < 10 )
                        set deletetimer to ( deletetimer + 1 )
            endif

            if ( deletetimer == 10 )
                        SetDelete, 1
            endif

            Return

endif

Также учтите, что пример “Object->SetDelete 1”, скорее всего, приведёт к тому, что игра «вылетит». Поэтому функцию лучше всего вызывать в локальном скрипте, прикреплённом к объекту, который мы будем удалять. Не стоит удалять предмет из инвентаря –нагрузка может изменяться неверно. Сначала стоит использовать функцию Drop и лишь затем Disable и SetDelete. Также всевозможные магические эффекты могут вызвать проблемы с последней функцией.

Пример: объект, которому прикрепляется скрипт, будет рассчитывать местоположение игрока и двигаться к нему с определённой скоростью. Как только он приблизится достаточно близко, он взорвётся (функция ExplodeSpell) и деактивируется. После этого объект подождёт пару фреймов, чтобы очистилась система заклинаний, а затем окончательно удалит себя.

Begin trapProjScript

short range
short initialized
short distance
short detonate
short triggered
float targx
float targy
float targz
float shiftx
float shifty
float shiftz
float currshift
float currx
float curry
float currz
float totaldist
float rate
float killtimer

if ( triggered == 1 )
            if ( killtimer < 4 )
                        set killtimer to ( killtimer + GetSecondsPassed )
            else
                        SetDelete 1
            endif

            return
endif

if ( MenuMode == 1 )
            return
endif

if ( initialized == 0 )
            set initialized to 1
            set range to 150
            set rate to 300
            set targx to ( player->GetPos X )
            set targy to ( player->GetPos Y )
            set targz to ( player->GetPos Z )
            set shiftx to ( targx – GetPos X )
            set shifty to ( targy – GetPos Y )
            set shiftz to ( targz – GetPos Z )
            set totaldist to ( ( shiftx * shiftx ) + ( shifty * shifty ) + ( shiftz * shiftz ) )
            set totaldist to GetSquareRoot totaldist
            if ( totaldist != 0 )
                        set shiftx to ( shiftx / totaldist )
                        set shiftx to ( shiftx * rate )
                        set shifty to ( shifty / totaldist )
                        set shifty to ( shifty * rate )
                        set shiftz to ( shiftz / totaldist )
                        set shiftz to ( shiftz * rate )
            else
                        set triggered to 1
                        return
            endif
endif

set distance to GetDistance "player"

if ( distance < range )
            set detonate to 1
else
            set currx to GetPos X
            set curry to GetPos Y
            set currz to GetPos Z
            set currshift to ( shiftx * GetSecondsPassed )
            set currx to ( currx + currshift )
            set currshift to ( shifty * GetSecondsPassed )
            set curry to ( curry + currshift )
            set currshift to ( shiftz * GetSecondsPassed )
            set currz to ( currz + currshift )

            if ( shiftx < 0 )
                        if ( currx < targx )
                                    set detonate to 1
                                    set currx to targx
                        else
                                    set detonate to 0
                        endif
            else
            if ( currx > targx )
                                    set detonate to 1
                                    set currx to targx
                        else
                                    set detonate to 0
                        endif
            endif

            if ( shifty < 0 )
                        if ( curry < targy )
                                    set detonate to 1
                                    set curry to targy
                        else
                                    set detonate to 0
                        endif
            else
                        if ( curry > targy )
                                    set detonate to 1
                                    set curry to targy
                        else
                                    set detonate to 0
                        endif
            endif

            if ( shiftz < 0 )
                        if ( currz < targz )
                                    set detonate to 1
                                    set currz to targz
                        else
                                    set detonate to 0
                        endif
            else
                        if ( currz > targz )
                                    set detonate to 1
                                    set currz to targz
                        else
                                    set detonate to 0
                        endif
            endif

            SetPos X currx
            SetPos Y curry
            SetPos Z currz

endif
if ( detonate == 1 )
            ExplodeSpell "proj_trap_spell"
            set triggered to 1
            disable
endif

end

Функции готовности к бою

GetWeaponDrawn (возвращает short)
GetSpellReadied (возвращает short)

if ( player -> GetWeaponDrawn )

Эти функции позволяют определить, достал ли персонаж оружие из ножен или готовиться ли он произнести заклинание соответственно.

Пример: этот глобальный скрипт выдаёт игроку специальные уведомительные сообщения в зависимости от того, готовиться ли он к бою.

Begin player_notifications

short weapstate
short spelstate

if ( player->GetWeaponDrawn )
            if ( weapstate != 1 )
                        set weapstate to 1
                        MessageBox "Игрок достал оружие."
            Endif
else
            if ( weapstate != 0 )
                        set weapstate to 0
                        MessageBox "Игрок убрал оружие."
            Endif
endif

if ( player->GetSpellReadied )
            if ( spelstate != 1 )
                        set spelstate to 1
                        MessageBox "Игрок готовится произнести заклинание."
            Endif
else
            if ( spelstate != 0 )
                        set spelstate to 0
                        MessageBox "Игрок отменил заклинание."
            Endif
endif

end