Репозитории II: разработка, часть 3
Запись опубликовал
645 просмотров
Начало здесь.
Пару дней ушло на "творческие метания"! Пытался совместить свои желания с возможностями игровой механики. Я совершенно точно знаю, что хочу видеть в моде - перемещение объекта из инвентаря в нужное хранилище без открытия последнего! И хотя SKSE существенно расширяет наши возможности, но определить скриптами текущий объект в инвентаре, пока не возможно, а значит невозможно и произвести над ним желаемые действия!
Но решение найдено! И хотя оно малопроизводительно (прямое управление объектом было бы на порядок быстрее), но оно элегантное и главное - работает!
Чтобы реализовать такое действие, внесем коррективы в существующий скрипт CB_PlayerAlias_Script, прикрепленный к псевдониму Player, нашего квеста CB_Player.
В событии при удалении объекта OnItemRemoved() мы предотвращали "потерю" репозиториев из инвентаря. Туда же я добавил код, анализирующий нажатие клавиш. Теперь, если при удалении объекта была нажата не одна, а две клавиши, то удаленный объект добавляется в соответствующее хранилище, а его ссылка в мире удаляется. Для игрока эта операция будет выглядеть как перемещение объекта из инвентаря в хранилище!
Благодаря использованию функции SKSE GetNumKeysPressed(), определяющей количество нажатых клавиш, мы избегаем конфликта с любыми модами, управляющими кнопками клавиатуры. При этом сами можем использовать любые комбинации клавиш в сочетании с клавишей, назначенной для выбрасывания объектов из инвентаря! Например, (удобнее для пальцев) "L-Shift + R" или "L-Ctrl + R" или "R-Alt + R" (неудобно, но работает!)...
Я уже протестировал этот код в игре, и мне понравилось! Я могу очень "гибко" выкладывать объекты в хранилища, и если надо переместить большое количество объектов, то комбинацию клавиш нажимать при подтверждении удаления!
Теперь обратим внимание на хранилище "-Все разное". Сейчас там складируются те категории объектов, доступ к которым мы хотели бы иметь отдельно. Мне представляется, что сортировки по категориям, внутри этого хранилища, будет достаточно. Вот этой задачей и займемся.
В окне Cell View находим нашу ячейку CB_Cell, а в ней хранилище CB_Misc. Открываем его для редактирования, переключаемся на вкладку скриптов. Поскольку функциональности имеющегося скрипта нам недостаточно, отключаем его, кнопка Remove, и добавляем новый скрипт, кнопка Add.
Заполняем все его свойства.
[/size]
Продолжение здесь
Пару дней ушло на "творческие метания"! Пытался совместить свои желания с возможностями игровой механики. Я совершенно точно знаю, что хочу видеть в моде - перемещение объекта из инвентаря в нужное хранилище без открытия последнего! И хотя SKSE существенно расширяет наши возможности, но определить скриптами текущий объект в инвентаре, пока не возможно, а значит невозможно и произвести над ним желаемые действия!
Но решение найдено! И хотя оно малопроизводительно (прямое управление объектом было бы на порядок быстрее), но оно элегантное и главное - работает!
Чтобы реализовать такое действие, внесем коррективы в существующий скрипт CB_PlayerAlias_Script, прикрепленный к псевдониму Player, нашего квеста CB_Player.
В событии при удалении объекта OnItemRemoved() мы предотвращали "потерю" репозиториев из инвентаря. Туда же я добавил код, анализирующий нажатие клавиш. Теперь, если при удалении объекта была нажата не одна, а две клавиши, то удаленный объект добавляется в соответствующее хранилище, а его ссылка в мире удаляется. Для игрока эта операция будет выглядеть как перемещение объекта из инвентаря в хранилище!
Благодаря использованию функции SKSE GetNumKeysPressed(), определяющей количество нажатых клавиш, мы избегаем конфликта с любыми модами, управляющими кнопками клавиатуры. При этом сами можем использовать любые комбинации клавиш в сочетании с клавишей, назначенной для выбрасывания объектов из инвентаря! Например, (удобнее для пальцев) "L-Shift + R" или "L-Ctrl + R" или "R-Alt + R" (неудобно, но работает!)...
Измененный скрипт
Scriptname CB_PlayerAlias_Script extends ReferenceAlias
{Следим за игроком}
Import Game
ObjectReference Property BoxWeapon Auto ; хранилище в ячейке CB_Cell
ObjectReference Property BoxArmor Auto
ObjectReference Property BoxPotion Auto
ObjectReference Property BoxScroll Auto
ObjectReference Property BoxFood Auto
ObjectReference Property BoxIngr Auto
ObjectReference Property BoxBook Auto
ObjectReference Property BoxMisc Auto
Ammo Property CB_Weapon Auto ; репозиторий
Armor Property CB_Armor Auto
Potion Property CB_Potion Auto
Scroll Property CB_Scroll Auto
Potion Property CB_Food Auto
Ingredient Property CB_Ingredient Auto
Book Property CB_Book Auto
MiscObject Property CB_Misc Auto
Int iNumKeysPressed = 0
Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference)
If akBaseObject == CB_Weapon
GetPlayer().UnEquipItem(CB_Weapon, False, True) ; снять одетый репозиторий
DisablePlayerControls(abMenu = True) ; запретить и скрыть меню
EnablePlayerControls(abMenu = True) ; разрешить меню
BoxWeapon.Activate(GetPlayer()) ; открыть хранилище
ElseIf akBaseObject == CB_Armor
GetPlayer().UnEquipItem(CB_Armor, False, True)
DisablePlayerControls(abMenu = True)
EnablePlayerControls(abMenu = True)
BoxArmor.Activate(GetPlayer())
ElseIf akBaseObject == CB_Potion
; GetPlayer().AddItem(CB_Potion, 1, True)
DisablePlayerControls(abMenu = True)
EnablePlayerControls(abMenu = True)
BoxPotion.Activate(GetPlayer())
ElseIf akBaseObject == CB_Scroll
GetPlayer().UnEquipItem(CB_Scroll, False, True)
DisablePlayerControls(abMenu = True)
EnablePlayerControls(abMenu = True)
BoxScroll.Activate(GetPlayer())
ElseIf akBaseObject == CB_Food
; GetPlayer().AddItem(CB_Food, 1, True)
DisablePlayerControls(abMenu = True)
EnablePlayerControls(abMenu = True)
BoxFood.Activate(GetPlayer())
ElseIf akBaseObject == CB_Ingredient
; GetPlayer().AddItem(CB_Ingredient, 1, True)
DisablePlayerControls(abMenu = True)
EnablePlayerControls(abMenu = True)
BoxIngr.Activate(GetPlayer())
ElseIf akBaseObject == CB_Book
GetPlayer().UnEquipItem(CB_Book, False, True)
DisablePlayerControls(abMenu = True)
EnablePlayerControls(abMenu = True)
BoxBook.Activate(GetPlayer())
ElseIf akBaseObject == CB_Misc
GetPlayer().UnEquipItem(CB_Misc, False, True)
DisablePlayerControls(abMenu = True)
EnablePlayerControls(abMenu = True)
BoxMisc.Activate(GetPlayer())
EndIf
EndEvent
Event OnItemRemoved(Form akBaseObject, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
iNumKeysPressed = Input.GetNumKeysPressed()
If iNumKeysPressed == 2
ObjectReference itemREF = FindClosestReferenceOfTypeFromRef(akBaseObject, GetPlayer(), 256)
If akBaseObject as Weapon
BoxWeapon.AddItem(itemREF, aiItemCount, True)
ElseIf akBaseObject as Ammo
BoxWeapon.AddItem(itemREF, aiItemCount, True)
ElseIf akBaseObject as Armor
BoxArmor.AddItem(itemREF, aiItemCount, True)
ElseIf akBaseObject as Potion
If (akBaseObject as Potion).isFood()
BoxFood.AddItem(itemREF, aiItemCount, True)
Else
BoxPotion.AddItem(itemREF, aiItemCount, True)
EndIf
ElseIf akBaseObject as Scroll
BoxScroll.AddItem(itemREF, aiItemCount, True)
ElseIf akBaseObject as Ingredient
BoxIngr.AddItem(itemREF, aiItemCount, True)
ElseIf akBaseObject as Book
BoxBook.AddItem(itemREF, aiItemCount, True)
ElseIf akBaseObject as MiscObject
BoxMisc.AddItem(itemREF, aiItemCount, True)
EndIf
itemREF.Disable()
itemREF.Delete()
EndIf
If akBaseObject == CB_Weapon
ReturnItem(akBaseObject, akDestContainer)
ElseIf akBaseObject == CB_Armor
ReturnItem(akBaseObject, akDestContainer)
ElseIf akBaseObject == CB_Potion
ReturnItem(akBaseObject, akDestContainer)
ElseIf akBaseObject == CB_Scroll
ReturnItem(akBaseObject, akDestContainer)
ElseIf akBaseObject == CB_Food
ReturnItem(akBaseObject, akDestContainer)
ElseIf akBaseObject == CB_Ingredient
ReturnItem(akBaseObject, akDestContainer)
ElseIf akBaseObject == CB_Book
ReturnItem(akBaseObject, akDestContainer)
ElseIf akBaseObject == CB_Misc
ReturnItem(akBaseObject, akDestContainer)
EndIf
EndEvent
Function ReturnItem(Form _BaseItem, ObjectReference _DestContainer)
If !_DestContainer
If GetPlayer().GetItemCount(_BaseItem) == 0
GetPlayer().AddItem(_BaseItem, 1, True)
EndIf
Else
If GetPlayer().GetItemCount(_BaseItem) == 0
_DestContainer.RemoveItem(_BaseItem, 1, True, GetPlayer())
EndIf
EndIf
EndFunction
Я уже протестировал этот код в игре, и мне понравилось! Я могу очень "гибко" выкладывать объекты в хранилища, и если надо переместить большое количество объектов, то комбинацию клавиш нажимать при подтверждении удаления!
Теперь обратим внимание на хранилище "-Все разное". Сейчас там складируются те категории объектов, доступ к которым мы хотели бы иметь отдельно. Мне представляется, что сортировки по категориям, внутри этого хранилища, будет достаточно. Вот этой задачей и займемся.
В окне Cell View находим нашу ячейку CB_Cell, а в ней хранилище CB_Misc. Открываем его для редактирования, переключаемся на вкладку скриптов. Поскольку функциональности имеющегося скрипта нам недостаточно, отключаем его, кнопка Remove, и добавляем новый скрипт, кнопка Add.
Новый скрипт
Scriptname CB_Box_MiscSwitch_Script extends ObjectReference Keyword Property VendorItemOreIngot Auto Keyword Property VendorItemGem Auto Keyword Property VendorItemAnimalHide Auto Keyword Property VendorItemAnimalPart Auto Keyword Property VendorItemSoulGem Auto ObjectReference Property BoxOre Auto ObjectReference Property BoxGem Auto ObjectReference Property BoxSoul Auto ObjectReference Property BoxAnim Auto Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) If akBaseItem as MiscObject If akBaseItem.HasKeyword(VendorItemOreIngot) Self.RemoveItem(akBaseItem, aiItemCount, True, BoxOre) ElseIf akBaseItem.HasKeyword(VendorItemGem) Self.RemoveItem(akBaseItem, aiItemCount, True, BoxGem) ElseIf akBaseItem.HasKeyword(VendorItemAnimalHide) || akBaseItem.HasKeyword(VendorItemAnimalPart) Self.RemoveItem(akBaseItem, aiItemCount, True, BoxAnim) ElseIf akBaseItem.HasKeyword(VendorItemSoulGem) Self.RemoveItem(akBaseItem, aiItemCount, True, BoxSoul) EndIf Else Self.RemoveItem(akBaseItem, aiItemCount, True, akSourceContainer) EndIf EndEvent
Заполняем все его свойства.

Продолжение здесь
0 Комментариев
Рекомендуемые комментарии
Комментариев нет
Для публикации сообщений создайте учётную запись или авторизуйтесь
Вы должны быть пользователем, чтобы оставить комментарий
Создать аккаунт
Зарегистрируйте новый аккаунт в нашем сообществе. Это очень просто!
Регистрация нового пользователяВойти
Уже есть аккаунт? Войти в систему.
Войти