Форум » Записи участника [Multigone]

Результаты поиска
Multigone  Offline  Сообщение №781 | Тема: Вопросы по скриптам Papyrus написано: 18 октября 2016, 22:19



832
AlexeyVN, можно этой SKSE-функцией:

; Sets whether the player knows this form
; Should only be used for Magic Effects,
; Words of Power, and Enchantments
Function SetPlayerKnows(bool knows) native


Код
MySomethingEnchantment.SetPlayerKnows(true)

Multigone  Offline  Сообщение №782 | Тема: Вопросы по скриптам Papyrus написано: 19 октября 2016, 11:53



832
grumpos, по дефолту время показа около 5 с. Возможно, это настраивается где-то в Settings.

Multigone  Offline  Сообщение №783 | Тема: Вопросы по скриптам Papyrus написано: 19 октября 2016, 16:18



832
SoulDiablo, задержку сделать легко, циферблат - проблема.

Добавлено (19 Октября 2016, 19:18)
---------------------------------------------
AlexeyVN, вот перечень всех меню, выбирай, что лучше подойдет (мое мнение - ничего):



Код
;    "InventoryMenu"
;    "Console"
;    "Dialogue Menu"
;    "HUD Menu"
;    "Main Menu"
;    "MessageBoxMenu"
;    "Cursor Menu"
;    "Fader Menu"
;    "MagicMenu"
;    "Top Menu"
;    "Overlay Menu"
;    "Overlay Interaction Menu"
;    "Loading Menu"
;    "TweenMenu"
;    "BarterMenu"
;    "GiftMenu"
;    "Debug Text Menu"
;    "MapMenu"
;    "Lockpicking Menu"
;    "Quantity Menu"
;    "StatsMenu"
;    "ContainerMenu"
;    "Sleep/Wait Menu"
;    "LevelUp Menu"
;    "Journal Menu"
;    "Book Menu"
;    "FavoritesMenu"
;    "RaceSex Menu"
;    "Crafting Menu"
;    "Training Menu"
;    "Mist Menu"
;    "Tutorial Menu"
;    "Credits Menu"
;    "TitleSequence Menu"
;    "Console Native UI Menu"
;    "Kinect Menu"

Multigone  Offline  Сообщение №784 | Тема: Вопросы по скриптам Papyrus написано: 19 октября 2016, 21:11 | Отредактировано: Multigone - 23 апреля 2020, 14:35



832
SoulDiablo, вот варианты:

1)

+ Заклинание должно иметь архетип Scripts.
+ Должно иметь продолжительность не меньше 61 с (лучше 1 день или больше, чтобы иметь гарантированные 60 сек. работы, даже если другие моды перками снижают общую Duration всех заклинаний - я так перестраховываюсь).
+ Если повторно скастовать его, а таймер не дошел до нуля, отсчет пойдет заново.


Код
Scriptname _TESTTEST20 Extends ActiveMagicEffect

Spell Property ThisSpell Auto ; Заклинание с этим эффектом. Заполняется обязательно.
Spell Property MyDevastatingSpell Auto ; Заклинание, уничтожающее все живое.
Activator Property MyClock Auto ; Активатор с моделью-часами. Если оставить none, ничего плохого не случится (таймера не будет).
Float Property MyStartTime = 60.0 Auto ; Начальный отсчет часов.

ObjectReference ClockRef
Float fTimer

EVENT OnEffectStart(Actor xT, Actor xC)
    ClockRef = xT.PlaceAtMe(MyClock)
    fTimer = MyStartTime
    OnUpdate()
ENDEVENT

EVENT OnUpdate()
    IF fTimer > 0.0
        ClockRef.SetAnimationVariableFloat("UcknownAnim", fTimer) ; Нужно знать название анимации для модели таймера.
        fTimer -= 1.0
        RegisterForSingleUpdate(1.00)
    ELSE
        GetTargetActor().DispelSpell(ThisSpell)
    ENDIF
ENDEVENT

EVENT OnEffectFinish(Actor xT, Actor xC)
    IF fTimer <= 0.0
        MyDevastatingSpell.Cast(xT)
    ENDIF
    ClockRef.Delete()
ENDEVENT

2)

+ Заклинание может иметь любой архетип.
+ Его продолжительность не имеет значения.
+ Если повторно скастовать его, появится новый таймер, каждый сработает в соотв. время.


Код
Scriptname _TESTTEST21 Extends ActiveMagicEffect

Spell Property MyDevastatingSpell Auto ; Заклинание, уничтожающее все живое.
Activator Property MyClock Auto ; Активатор с моделью-часами. Если оставить none, ничего плохого не случится (таймера не будет).
Float Property MyStartTime = 60.0 Auto ; Начальный отсчет часов.

EVENT OnEffectStart(Actor xT, Actor xC)
    ObjectReference ClockRef = xT.PlaceAtMe(MyClock)
    WHILE MyStartTime > 0.0
        ClockRef.SetAnimationVariableFloat("UcknownAnim", MyStartTime) ; Нужно знать название анимации для модели таймера.
        Utility.Wait(1.0)
        MyStartTime -= 1.0
    ENDWHILE
    MyDevastatingSpell.Cast(xT)
    ClockRef.Delete()
ENDEVENT

Ничего не проверял, кроме компилируемости. Если модели таймера нет, отсчет не будет показан, а заклинание сработает в положенное время.

***

PS: Если вообще не учитывать модель таймера, варианты могут быть упрощены до:

1)

+ Теперь эффект должен иметь архетип ValueMod (с параметром "Morality", к примеру).
+ Поставить заклинанию нужную продолжительность, по окончании действия оно сработает.


Код
Scriptname _TESTTEST20 Extends ActiveMagicEffect

Spell Property MyDevastatingSpell Auto ; Заклинание, уничтожающее все живое.

EVENT OnEffectFinish(Actor xT, Actor xC)
    MyDevastatingSpell.Cast(xT)
ENDEVENT

2)


Код
Scriptname _TESTTEST21 Extends ActiveMagicEffect

Spell Property MyDevastatingSpell Auto ; Заклинание, уничтожающее все живое.

EVENT OnEffectStart(Actor xT, Actor xC)
    Utility.Wait(60.0)
    MyDevastatingSpell.Cast(xT)
ENDEVENT

Multigone  Offline  Сообщение №785 | Тема: Вопросы по скриптам Papyrus написано: 20 октября 2016, 11:39 | Отредактировано: Multigone - 20 октября 2016, 11:44



832
AlexeyVN, в общем, сделал, хотя не совсем так, как планировалось. Итак:

- игрок активирует алтарь.
- опционально показывается сообщение, что нужно выбросить из инвентаря зачарованный предмет.
- открывается инвентарь.
- если игрок выбрасывает незачарованный предмет, он возвращается обратно в инвентарь.
- если зачарованный, то меню закрывается, он теряет зачарование, плюс:
    - самопальные оружие и доспех - нормальный процесс.
    - уровневое оружие теряет заточку.
    - уровневый доспех никак не обрабатывается (нужно дополнять скрипт форм-листами, проблема в SKSE).
    - уникальные предметы не обрабатываются (нужно дополнять списком всех уникальных вещей).
- если игрок выбрасывает стек из нескольких зачарованных предметов (от 5 по дефолту), то они теряют зачарование, один из них помещается на алтарь, остальные будут брошены рядом.
- когда игрок закрывает меню вручную, ничего не происходит.


Код
Scriptname _TESTTEST22 Extends ObjectReference ; На алтарь.

Message Property MyMessage Auto ; Опционально сообщение (можно не заполнять). Должно иметь строки: 0 - да, 1 - нет.
_TESTTEST23 Property L Auto ; Вместо _TESTTEST23 указать реальное название скрипта, присоединенного к алиасу игрока! И обязательно заполняется в СК!

EVENT OnActivate(ObjectReference xR)
    GoToState("S")
    IF xR AS Actor && (!MyMessage || !MyMessage.Show())
        L.GoToState("S")
        L.Altar = Self
        Input.TapKey(Input.GetMappedKey("Quick Inventory"))
    ENDIF
    GoToState("")
ENDEVENT

STATE S
    EVENT OnActivate(ObjectReference xR)
    ENDEVENT
ENDSTATE

Код
Scriptname _TESTTEST23 Extends ReferenceAlias ; На алиас игрока.

ObjectReference Property Altar Auto Hidden

EVENT OnInit()
    RegisterForMenu("InventoryMenu")
ENDEVENT

STATE S
    Event OnItemRemoved(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
        IF !akItemReference || akDestContainer
        ELSEIF akBaseItem as Weapon && (akBaseItem as Weapon).GetEnchantment()
            Form xF = ((akItemReference.GetBaseObject()) AS Weapon).GetTemplate()
            IF xF
                Input.TapKey(0x1)
                akItemReference.Delete()
                akItemReference = Altar.PlaceAtMe(xF, aiItemCount)
                akItemReference.MoveTo(Altar, 0.0, 0.0, 200.0) ; Доработать так, как необходимо.
            ELSE
                Debug.Notification("Предмет уникален.") ; Предмет имеет зачарование, но не имеет основополагающего оружия. Нужно рассматривать каждый случай отдельно (создавать лист).
            ENDIF
        ELSEIF akBaseItem as Armor && (akBaseItem as Armor).GetEnchantment()
            Form xF ;= ((akItemReference.GetBaseObject()) AS Armor).GetTemplate() ; На текущий момент такой функции в SKSE нет, нужно создавать несколько листов.
            IF xF
                Input.TapKey(0x1)
                akItemReference.Delete()
                akItemReference = Altar.PlaceAtMe(xF, aiItemCount) ; Доработать так, как необходимо.
                akItemReference.MoveTo(Altar, 0.0, 0.0, 200.0)
            ELSE
                Debug.Notification("Предмет уникален.")
            ENDIF
        ELSEIF akItemReference.GetEnchantment()
            Input.TapKey(0x1)
            akItemReference.MoveTo(Altar, 0.0, 0.0, 200.0) ; Доработать так, как необходимо.
            akItemReference.SetEnchantment(none, 0.0)
        ELSE
            GetRef().AddItem(akItemReference, aiItemCount, true)
        ENDIF
    ENDEVENT

    EVENT OnMenuClose(string menuName)
        GoToState("")
    ENDEVENT
ENDSTATE

Multigone  Offline  Сообщение №786 | Тема: Вопросы по скриптам Papyrus написано: 20 октября 2016, 18:18



832
AlexeyVN, т.е. то, что некоторые проблемы остались, не смущает?

Цитата AlexeyVN

можно как нибудь подсветку сделать

Вряд ли.

Multigone  Offline  Сообщение №787 | Тема: Вопросы по скриптам Papyrus написано: 20 октября 2016, 19:02 | Отредактировано: Multigone - 28 октября 2016, 16:17



832
AlexeyVN, что-то у этого...


Код
WornObject.GetEnchantment(actorRef, 0, 0)

Код
WornObject.SetEnchantment(actorRef, 0, 0, None, 0)
... много лишних аргументов. В SKSE 1.7.3 такого нет (Upd: есть в WornObject.psc).

Идея понятна. Перебираются все надетые на актера вещи, и если какая-либо из них зачарована, зачарование снимается (что такое WornObject?). Это в теории.

Еще: все операции c зачарованием (Get / Set) для ObjectReference могут проводиться только в случае, если это зачарование было наложено игроком. Если зачарование указано в базовом объекте, то попытка применить на таком референсе akItemReference.SetEnchantment(none, 0.0) приведет к вылету из игры.

Multigone  Offline  Сообщение №788 | Тема: Вопросы по скриптам Papyrus написано: 7 ноября 2016, 19:58



832
Lexo, добавление стандартных компаньонов происходит в квесте DialogueFollower. Еще можно изучить это. Расстояние между объектами определяется функцией...

; Calculates the distance between this reference and another - both must either be in the same interior, or same worldspace
float Function GetDistance(ObjectReference akOther) native


Код
Float f = Ref1.GetDistance(Ref2)

PS: Расстояние следования за игроком задается в FollowerPackageTemplate, однако ничто не мешает сделать свой пакет.

Multigone  Offline  Сообщение №789 | Тема: Вопросы по скриптам Papyrus написано: 8 ноября 2016, 15:06 | Отредактировано: Multigone - 8 ноября 2016, 15:16



832
grumpos, если заклинание модное и известно, можно поменять его Delivery на Target Actor, тогда Cast() будет накладывать заклинание на указанную цель, а не туда, куда смотрит игрок.

А по сути, есть вот что:

; Sets this actor's head tracking target, optionally forcing it as their pathing look-at target
Function SetLookAt(ObjectReference akTarget, bool abPathingLookAt = false) native


Код
Actor1.SetLookAt(Ref1)
Actor1.SetLookAt(none)
Не работает с оружием в руках (?) или в режиме от первого лица.

Еще в Dialogue Scene Action есть отделение с 3 настройками Headtracking, но не знаю, будет ли в этом случае вращаться камера. Для примера можно посмотреть квест DB09.

Еще можно попробовать (не проверял, не уверен) установить угол камеры игрока функцией SetAngle(), если игрок находится в режиме первого лица, но думаю, выглядеть это будет не очень (если вообще будет работать).

Еще можно (?) заставить игрока творить заклинание пакетом UseMagic.

Multigone  Offline  Сообщение №790 | Тема: Вопросы по скриптам Papyrus написано: 20 ноября 2016, 08:20



832
Lexo, можно лишь с помощью SKSE узнать, содержал ли камень душу изначально, т.е. что было указано в строке "Soul" этой формы. Если камень изначально пуст, нельзя вообще никак узнать, заполнен ли он, когда:
1) он содержит душу меньшей величины, чем камень, или...
2) он содержит душу соотв. величины, но форма не имеет ссылки на изначально полную версию (Linked to).

Артефакт Азуры всегда подходит под один из этих случаев, значит, определить величину души, или факт содержания души, невозможно.

Multigone  Offline  Сообщение №791 | Тема: Вопросы по скриптам Papyrus написано: 23 ноября 2016, 18:37 | Отредактировано: Multigone - 23 ноября 2016, 18:38



832
Crunatus, нужен SKSE:


Код
IF UI.IsMenuOpen("InventoryMenu") || UI.IsMenuOpen("ContainerMenu")
    Input.TapKey(0x1)
    ; Input.TapKey(Input.GetMappedKey("Pause")) ; ?
ENDIF

Multigone  Offline  Сообщение №792 | Тема: Вопросы по Creation Kit (продолжение старой темы) написано: 8 декабря 2016, 12:29 | Отредактировано: Multigone - 8 декабря 2016, 13:01



832
Crunatus, похоже, это условие не работает (по аналогии с GetQuestVariable). Вместо него нужно использовать GetVMScriptVariable / GetVMQuestVariable.
Ссылка 1, ссылка 2 (про флаг Conditional).

Задача GetVMScriptVariable - проверить значение переменной скрипта (параметр 2) на референсе объекта (1).

Multigone  Offline  Сообщение №793 | Тема: Вопросы по скриптам Papyrus написано: 24 декабря 2016, 19:25



832
Lexo, есть 2 способа:

1) На примере маг. эффекта.


Код
Event OnEffectStart(Actor xT, Actor xC)
    RegisterForAnimationEvent(xT, "weaponSwing")
    RegisterForAnimationEvent(xT, "weaponLeftSwing")
ENDEVENT

Event OnAnimationEvent(ObjectReference akSource, string asEventName)
    IF asEventName == "weaponSwing"
        ; удар правой
    ELSE
        ; удар левой
    ENDIF

;   Debug.Notification(asEventName)

EndEvent

2) Используя SKSE:


Код
Event OnEffectStart(Actor xT, Actor xC)
    RegisterForActorAction(0)

; ActionTypes
; 0 - Weapon Swing (Melee weapons that are swung, also barehand)
; 1 - Spell Cast (Spells and staves)
; 2 - Spell Fire (Spells and staves)
; 3 - Voice Cast
; 4 - Voice Fire
; 5 - Bow Draw
; 6 - Bow Release
; 7 - Unsheathe Begin
; 8 - Unsheathe End
; 9 - Sheathe Begin
; 10 - Sheathe End

ENDEVENT

Event OnActorAction(int actionType, Actor akActor, Form source, int slot)
    IF slot == 1
        ; удар правой
    ELSE
        ; удар левой
    ENDIF

; Slots
; 0 - Left Hand
; 1 - Right Hand
; 2 - Voice

EndEvent

Multigone  Offline  Сообщение №794 | Тема: Вопросы по Creation Kit (продолжение старой темы) написано: 2 января 2017, 01:33



832
DirtyLol, используя SKSE, можно сделать немного по-другому (если нужно затяжное поглощение cо множественными наложениями):

- меняем архетип на Value Mod - Health (Stamina/Magicka), флаг No Death Dispel снимаем.
- добавляем скрипт:


Код
Scriptname _TESTTEST24 Extends ActiveMagicEffect

Actor xA
Float fMag

EVENT OnEffectStart(Actor xT, Actor xC)
    xA = xC
    fMag = GetMagnitude()
    RegisterForSingleUpdate(1.0)
ENDEVENT

EVENT OnUpdate()
    xA.RestoreActorValue("Health", fMag)
                     ; Вместо Health нужно написать Stamina или Magicka, если исходный эффект "поглощает" силу или магию.
    RegisterForSingleUpdate(1.0)
ENDEVENT

- проверяем результат в игре.

Проблема: восстановление атрибута происходит рывками, а не плавненько, как раньше. Этого можно избежать, если использовать не команду RestoreAV, а накладывать на источник заклинание продолжительностью 1с, восстанавливающее атрибут (создаются соотв. заклинания, меняется скрипт).

Multigone  Offline  Сообщение №795 | Тема: Вопросы по скриптам Papyrus написано: 3 января 2017, 12:14 | Отредактировано: Multigone - 23 апреля 2020, 09:44



832
Lexo, на алиас игрока:


Код
Scriptname _TESTTEST26 extends ReferenceAlias

Keyword property _LEXO_Agni Auto
Spell Property _LEXO_FireWave auto

Actor xP
Bool bL

EVENT OnInit()
    xP = GetActorReference()
ENDEVENT

EVENT OnRaceSwitchComplete()
    xP = GetActorReference()
ENDEVENT

EVENT OnObjectEquipped(Form xF, ObjectReference xR)
    IF xF AS Weapon && xF.HasKeyword(_LEXO_Agni) && !bL
        bL = true
        Utility.Wait(0.001)
;        IF xP.GetEquippedWeapon(0).GetEnchantment().HasKeyword(_LEXO_Agni) || WornObject.GetEnchantment(xP, 1, 0).HasKeyword(_LEXO_Agni) ; Если чары оружия имеют кейворд (SKSE).
        IF xP.GetEquippedWeapon(0).HasKeyword(_LEXO_Agni) ; Если оружие имеет кейворд.
            RegisterForAnimationEvent(xP, "weaponSwing")
        ELSE
            UnRegisterForAnimationEvent(xP, "weaponSwing")
        ENDIF

;        IF xP.GetEquippedWeapon(1).GetEnchantment().HasKeyword(_LEXO_Agni) || WornObject.GetEnchantment(xP, 0, 0).HasKeyword(_LEXO_Agni)
        IF xP.GetEquippedWeapon(1).HasKeyword(_LEXO_Agni)
            RegisterForAnimationEvent(xP, "weaponLeftSwing")
        ELSE
            UnRegisterForAnimationEvent(xP, "weaponLeftSwing")
        ENDIF
        bL = false
    ENDIF
ENDEVENT

EVENT OnObjectUnequipped(Form xF, ObjectReference xR)
    OnObjectEquipped(xF, xR)
ENDEVENT

Event OnAnimationEvent(ObjectReference akSource, string asEventName)
    _LEXO_FireWave.Cast(xP)
EndEvent

Для НПС эти анимации не регистрируются (событие не срабатывает). Я пробовал эти, тоже нет:

RegisterForAnimationEvent(xT, "AttackWinStart")
RegisterForAnimationEvent(xT, "tailCombatState")
RegisterForAnimationEvent(xT, "attackStartLeftHand")
RegisterForAnimationEvent(xT, "attackStart")

Проверил, вроде работает.

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

Lexo, еще проверь:

- вешается на алиас игрока.
- квест алиаса должен быть запущен.
- заполняются Property (для проверки можно взять Firerball).
- у экипированного оружия должно быть это ключ. слово (для проверки WeapMaterialIron).

Multigone  Offline  Сообщение №796 | Тема: Вопросы по Creation Kit (продолжение старой темы) написано: 8 января 2017, 13:24



832
gangrena1972, решается скриптом на квесте:


Код
Scriptname _DefRun extends Quest

EVENT OnInit()
    IF !IsCompleted()
        Start()
    ENDIF
ENDEVENT

Multigone  Offline  Сообщение №797 | Тема: Вопросы по скриптам Papyrus написано: 9 января 2017, 09:25 | Отредактировано: Multigone - 9 января 2017, 09:28



832
Цитата Lexo

желательно реф


Чтобы управлять референсом предмета, нужно его знать. Значит, предмет должен быть в алиасе. На активатор:


Код
Scriptname _TESTTEST27 extends objectReference ; если предмет создается алиасом (или находится там).

ReferenceAlias Property ItemAlias auto

Event OnLoad()
    objectReference ItemRef = ItemAlias.GetReference()
    IF Game.GetPlayer().GetItemCount(ItemRef)
        ItemRef.MoveTo(Self, 0.0, 0.0, 25.0) ; располагает предмет на 25 юнитов выше активатора.
        while !ItemRef.is3dloaded()
            utility.wait(0.05)
        endwhile
        ItemRef.setMotionType(Motion_Keyframed) ; если нужно, чтобы предмет не улетел куда-нибудь.
    ENDIF
endEvent

Активатор должен иметь модель, можно Effects\FXEmptyObject.nif.

Dsion, если накрутить много действий на oninit (или просто вставить ожидание), он сработает несколько раз. Проверь свой скрипт через debug.notification(utility.randomfloat()), и там спавнится 3-4 меча. У меня это так работает для всех oninit.

Multigone  Offline  Сообщение №798 | Тема: Вопросы по Creation Kit (продолжение старой темы) написано: 16 января 2017, 20:36 | Отредактировано: Multigone - 16 января 2017, 20:42



832
Lokimo, находишь модель виз. эффекта, открываешь ее в Nifscope, ищешь все строчки типа BSEffectShaderProperty, указываешь свои цвета и пути к текстурам. Ванильные ресурсы запакованы в Meshes.bsa, Textures.bsa; открываются BSA Browser. Nifscope открывает только модели внутри Data/Meshes.



Сохраняешь модель, можно под старым именем, но в свою директорию (Data/Meshes/MyModDir). Используешь ее в СК.

Multigone  Offline  Сообщение №799 | Тема: Вопросы по скриптам Papyrus написано: 17 января 2017, 20:29



832
Цитата Dsion

У предметов в инвентаре вообще нету refid


Не совсем так. Они есть, просто их нельзя получить с помощью переменных, таких, как:

Код
Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference)
Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)

Тем не менее, если в окно объектов кинуть кинжал, а в каком-нибудь скрипте заполнить им ObjectReference Property _TESTREFR Auto, то таким кинжалом можно управлять, когда он находится в инвентаре и сложен в стек - например, выбросить его оттуда с помощью _TESTREFR.MoveTo(Game.GetPlayer()).

Если к референсу этого кинжала добавить скрипт, то его self будет хранить информацию о себе, даже когда он попадает в инвентарь:


Код
EVENT OnContainerChanged(ObjectReference xNew, ObjectReference xOld)
    IF xNew && self == _TESTREFR
        Debug.MessageBox("+")
    ENDIF
ENDEVENT



Multigone  Offline  Сообщение №800 | Тема: Вопросы по скриптам Papyrus написано: 17 января 2017, 20:48 | Отредактировано: Multigone - 17 января 2017, 20:52



832
Dsion, если предметы были добавлены в инвентарь не подбором из мира, то у них, конечно, не будет своего id. Когда они будут выброшены, игра сформирует временный refid для этого стека (как если бы использовалась placeatme()). Наверное, поэтому, когда выбрасывается сразу весь стек из камней душ, вместо одной модели появляется несколько - стек из купленных / созданных (не имевших своего id) и отдельным предметом каждый из найденных в мире.

Multigone  Offline  Сообщение №801 | Тема: Вопросы по скриптам Papyrus написано: 30 января 2017, 21:05



832
Lexo, если проблему с выбрасыванием нужного референса щита (среди одинаковых) не решил, то у меня для тебя хорошие новости.

 
Код
ObjectReference Property xC1 Auto ; реф. пустого контейнера.
ObjectReference Property xC2 Auto ; реф. пустого контейнера.
ObjectReference Property PlayerRef Auto ; игрок.

FUNCTION F()
    Armor xARMO = (PlayerRef AS Actor).GetEquippedShield()
    IF xARMO
        Int iC = PlayerRef.GetItemCount(xARMO)
        IF iC > 99 ; слишком большое кол-во не обрабатываем.
        ELSEIF iC > 1
            WHILE iC
                PlayerRef.RemoveItem(xARMO, 1, true, xC1)
                IF (PlayerRef AS Actor).GetEquippedShield()
                    xC1.RemoveItem(xARMO, 1, true, xC2)
                    iC -= 1
                ELSE
                    PlayerRef.RemoveItem(xARMO, PlayerRef.GetItemCount(xARMO), true, xC2)
                    xC1.RemoveItem(xARMO, 1, true, PlayerRef)
                    PlayerRef.DropObject(xARMO, 1)
                    iC = 0
                ENDIF
            ENDWHILE
            xC2.RemoveAllItems(PlayerRef)
        ELSE
            PlayerRef.DropObject(xARMO, 1)
        ENDIF
    ENDIF
ENDFUNCTION

Multigone  Offline  Сообщение №802 | Тема: Вопросы по скриптам Papyrus написано: 2 февраля 2017, 19:45



832
Нарада


Код
Quest Property mQuest  Auto  
Int property QStage auto
function OnActivate(ObjectReference akActionRef)
    mQuest.SetStage(QStage)
    (akActionRef as actor).evaluatepackage()
endFunction

Multigone  Offline  Сообщение №803 | Тема: Вопросы по Creation Kit (продолжение старой темы) написано: 7 февраля 2017, 14:15



832
Kepper, актерам же нельзя добавлять / удалять перки динамически.

Multigone  Offline  Сообщение №804 | Тема: Вопросы по скриптам Papyrus написано: 7 февраля 2017, 14:31



832
Цитата Dsion

Если твой скрипт наследует ActiveMagicEffect - это означает, что ты в любом месте можешь прописать Dispel() и это должно снять именно этот эффект с того, на кого он наложен.


Возможно, Self для ActiveMagicEffect определяет скрипт, а не активный эффект. Я видел такую конструкцию:


Код
MyMagEffectScript X = Self

Хотя по общим правилам там должно быть написано:


Код
MyMagEffectScript X = Self AS MyMagEffectScript

А это далеко не одно и то же.

Кстати, Dispel() и GetBaseObject() вообще не работают. По крайней мере, у меня. Они должны применяться к ActiveMagicEffect объекту - но функции, которая возвращала бы его, в ванильном папирусе нет.

Multigone  Offline  Сообщение №805 | Тема: Вопросы по скриптам Papyrus написано: 7 февраля 2017, 15:10



832
Dsion, забавно, сколько времени был уверен, что Dispel() не работает (сто раз проверял), сейчас завел СК - заработало, ***. Кое-что придется переписывать, избавляться от DispelSpell и Property.

Multigone  Offline  Сообщение №806 | Тема: Вопросы по скриптам Papyrus написано: 7 февраля 2017, 20:03 | Отредактировано: Multigone - 7 февраля 2017, 21:00



832
Dsion, всегда думал, что self - это объект, а скрипт расширяет форму, а не является ей. Ну да ладно, я-то C++ не изучал. Про cast знаю - float as string всегда, а string as float иногда. В любом случае, спасибо за стену текста.)

PitrPokir, если эффект нужно снять извне (не из его скрипта), то DispelSpell. Или наложить другой эффект с флагом Dispel и ключ. словами. Первый снимает все копии всех эффектов этого заклинания, второй способ может снять копии только одного из эффектов заклинания, но требует ключ. слов.

Чтобы точно знать ID каждой копии эффекта (для применения Dispel()), можно использовать массив где-нибудь в квесте, который будет заполняться при старте каждого отдельного эффекта, при условии, что они накладываются только на одного актера и не строго одновременно.

А, в этом случае хватит и одной переменной. Скрипт на эффекте призрака будет примерно таким:

Код
scriptname myghostspellscript extends activemagiceffect

spell  property mymenuspell auto
myquestscript property s auto
activemagiceffect x

event oneffectstart(actor t, actor c)
    mymenuspell.cast(game.getplayer())
    int ic = 3000
    while !s.q && ic
        utility.wait(0.001)
        ic -= 1
    endwhile
    if s.q
        x = s.q
        s.q = none
    endif
endevent

event oneffectfinish(actor t, actor c) ;
    x.dispel()
endevent

event ondying(actor k)
    x.dispel()
endevent

Скрипт на эффекте игрока:


Код
scriptname mymenuspellscript extends activemagiceffect

myquestscript property s auto

event oneffectstart(actor t, actor c)
    s.q = self as activemagiceffect
endevent

Скрипт на квесте (одна переменная):


Код
scriptname myquestscript extends quest

activemagiceffect property q auto hidden

Можно доп. защитить скрипт - когда кол-во призраков = 0 (глобальная), снимаются не отдельные эффекты, а dispelspell(mymenuspell).

Multigone  Offline  Сообщение №807 | Тема: Вопросы по скриптам Papyrus написано: 8 февраля 2017, 23:50



832
kelamor, можно через OnMagicEffectApply, как подсказывает PitrPokir,  или onhit. Но лучше через OnObjectEquipped(Form akBaseObject, ObjectReference akReference), он срабатывает один раз при использовании зелья, а не все свободное время, пока на игроке есть хоть один долговременный маг. эффект.

Multigone  Offline  Сообщение №808 | Тема: Вопросы по скриптам Papyrus написано: 10 февраля 2017, 12:01 | Отредактировано: Multigone - 10 февраля 2017, 15:35



832
AlexeyVN, ругается потому, GetEquippedWeapon() возвращает Weapon, а ты пытаешься к нему применить функцию, предназначенную для ObjectReference.

Используя SKSE:


Код
Scriptname _TESTTEST30 extends objectReference

bool function CheckTempering(bool rightHand = true, float hold = 1.6)
    actor a = Game.GetPlayer()
    if a.GetEquippedWeapon(!rightHand)
        return wornobject.GetItemHealthPercent(a, rightHand as int, 0) < hold
    endif
endfunction

; rightHand:
; false - левая / обе
; true - правая / обе

;    примеры:
;    If CheckTempering(true, 1.5) == true ; проверяем оружие в правой на заточку 1.5.
;        Debug.MessageBox("Оружие можно улучшить")
;    Else
;        Debug.MessageBox("Оружие максимально улучшено") ; или оружия нет в указанной руке.
;    EndIf

;    If CheckTempering()

Upd. 18:28

Multigone  Offline  Сообщение №809 | Тема: Вопросы по скриптам Papyrus написано: 13 февраля 2017, 10:56 | Отредактировано: Multigone - 13 февраля 2017, 10:58



832
PitrPokir,


Код
ReferenceAlias[] Property AliasArray Auto

ReferenceAlias CurrentFilled
Bool Slave

;;;

    Int Num = AliasArray.Length
    While Num > 0
        Num -= 1
        if AliasArray[Num].ForceRefIfEmpty(Ghost)
            CurrentFilled = AliasArray[Num];
            Slave = true
            Num = 0
        endif
    EndWhile

Multigone  Offline  Сообщение №810 | Тема: Вопросы по скриптам Papyrus написано: 14 февраля 2017, 14:18



832
Цитата gangrena1972

как


Код
; из этого квеста.

(getowningquest() as DLC1_NPCMentalModelScript).PlayerSettled = true

; из др. мест.

quest Property DLC1NPCMentalModel auto

(DLC1NPCMentalModel as DLC1_NPCMentalModelScript).PlayerSettled = true

; или

((game.getformfromfile(0x2b6e, "dawnguard.esm") as quest) as DLC1_NPCMentalModelScript).PlayerSettled = true

Форум » Записи участника [Multigone]
Поиск:





Ответ на жалобу смотрите в разделе жалоб