Начало здесь
Сначала хотел отредактировать предыдущий дневник, но потом подумал, какого черта, это же дневник, а не инструкция прямого действия! А поводом к такому решению послужило событие, заставившее меня отказаться от использования метода добавления в хранилище, разработанное на предыдущем шаге.
Я нашел решение - прямой доступ к текущей записи инвентаря! То, что вчера казалось невозможным, сегодня реализуется парой строчек кода!
Скрипт
CB_PlayerAlias_Script я откатил до предыдущего состояния, проще говоря, отредактировал, убрав обработку по нажатию клавиш. И создал новый скрипт.
Для решения текущей задачи, я создал скрипт
CB_PlayerQuest_Script в нашем квесте
CB_Player.

Звучит скрипт так. Определиться когда открыто меню инвентаря. Если нужное меню открыто, ожидать нажатия клавиши (в данном случае Back Space). И если такая клавиша нажата, получить FormID текущей записи, по которой определить объект и отправить его в соответствующее хранилище.
Scriptname CB_PlayerQuest_Script extends Quest ObjectReference Property BoxWeapon AutoObjectReference Property BoxArmor AutoObjectReference Property BoxPotion AutoObjectReference Property BoxScroll AutoObjectReference Property BoxFood AutoObjectReference Property BoxIngr AutoObjectReference Property BoxBook AutoObjectReference Property BoxMisc AutoEvent OnInit() RegisterForMenu("InventoryMenu") EndEventEvent OnMenuOpen(String MenuName) If MenuName == "InventoryMenu" RegisterForKey(14) EndIfEndEventEvent OnMenuClose(String MenuName) If MenuName == "InventoryMenu" UnregisterForKey(14) EndIfEndEventEvent OnKeyDown(Int KeyCode) If KeyCode == 14 int formid formid = UI.Getint("InventoryMenu", "_root.Menu_mc.inventoryLists.itemList.selectedEntry.formId") form selectedForm = Game.GetForm(formid) If selectedForm as Weapon Game.GetPlayer().RemoveItem(selectedForm, 1, True, BoxWeapon) ElseIf selectedForm as Armor Game.GetPlayer().RemoveItem(selectedForm, 1, True, BoxArmor) ElseIf selectedForm as Potion If (selectedForm as Potion).isFood() Game.GetPlayer().RemoveItem(selectedForm, 1, True, BoxFood) Else Game.GetPlayer().RemoveItem(selectedForm, 1, True, BoxPotion) EndIf ElseIf selectedForm as Scroll Game.GetPlayer().RemoveItem(selectedForm, 1, True, BoxScroll) ElseIf selectedForm as Ingredient Game.GetPlayer().RemoveItem(selectedForm, 1, True, BoxIngr) ElseIf selectedForm as Book Game.GetPlayer().RemoveItem(selectedForm, 1, True, BoxBook) ElseIf selectedForm as MiscObject Game.GetPlayer().RemoveItem(selectedForm, 1, True, BoxMisc) EndIf EndIf EndEvent
Не забываем заполнить свойства скрипта.

Сохраняем результат работы.
Тестирование в игре показало отличную скорость реакции на нажатие клавиши и стабильную работу.
А теперь вернемся и закончим предыдущий шаг - фильтрование объектов в категории Разное. Мы повесили скрипт на хранилище "
-Все разное", он работает - сортирует объекты по нужным хранилищам, но у нас нет доступа к этим хранилищам. Вот его и сделаем сейчас!
Меня устраивал метод доступа к хранилищам через меню, и хотя я стараюсь избегать частого его использования, все же воспользуюсь им и сейчас.
В окне
Object Window выбираем категорию
Message, и в таблице справа, жмем ПКМ и выбираем пункт
New.

Я создал три объекта
Message, для отображения трех групп кнопок, иначе они не поместятся на экране.



Наверное, проводятся какие-то работы на сайте, потому что блог лишен всех кнопок управления форматированием, а открытие и закрытие черновика "ломает" уже готовый (форматированный текст). Но я все же продолжу - не хочу терять время...
Меню будет вызываться из двух "режимов". Первый, когда инвентарь закрыт, нажатие кнопки Back Space откроет начальное меню, из которого, по цепочке, можно получить доступ ко всем кнопкам, и вызвать любое хранилище. Второй, когда инвентарь открыт, нажатие на репозиторий "-Все разное" откроет третью часть меню, для доступа к разному.
Для оптимизации, чтобы не использовать одинаковый вызов меню в двух скриптах одного квеста, я вызываю функцию из скрипта квеста.
Ниже представлены измененные скрипты псевдонима и квеста.
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
;Message Property CB_Message Auto
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())
(GetOwningQuest() as CB_PlayerQuest_Script).ShowMenu03()
EndIf
EndEvent
Event OnItemRemoved(Form akBaseObject, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
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
Scriptname CB_PlayerQuest_Script extends Quest
Import Game
ObjectReference Property BoxWeapon Auto
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
ObjectReference Property BoxOre Auto
ObjectReference Property BoxAnim Auto
ObjectReference Property BoxGem Auto
ObjectReference Property BoxSoul Auto
Message Property CB_Message01 Auto
Message Property CB_Message02 Auto
Message Property CB_Message03 Auto
Bool isMenuOpen = False
Event OnInit()
RegisterForMenu("InventoryMenu")
RegisterForKey(14)
EndEvent
Event OnMenuOpen(String MenuName)
If MenuName == "InventoryMenu"
isMenuOpen = True
EndIf
EndEvent
Event OnMenuClose(String MenuName)
If MenuName == "InventoryMenu"
isMenuOpen = False
EndIf
EndEvent
Event OnKeyDown(Int KeyCode)
If KeyCode == 14
If isMenuOpen
Int countID = 0
Int iNumKeysPressed = Input.GetNumKeysPressed()
Int formID = UI.Getint("InventoryMenu", "_root.Menu_mc.inventoryLists.itemList.selectedEntry.formId")
If formid
form selectedForm = Game.GetForm(formID)
If iNumKeysPressed == 2
countID = UI.Getint("InventoryMenu", "_root.Menu_mc.inventoryLists.itemList.selectedEntry.count")
Else
countID = 1
EndIf
If selectedForm as Weapon
GetPlayer().RemoveItem(selectedForm, countID, True, BoxWeapon)
ElseIf selectedForm as Ammo
GetPlayer().RemoveItem(selectedForm, countID, True, BoxWeapon)
ElseIf selectedForm as Armor
GetPlayer().RemoveItem(selectedForm, countID, True, BoxArmor)
ElseIf selectedForm as Potion
If (selectedForm as Potion).isFood()
GetPlayer().RemoveItem(selectedForm, countID, True, BoxFood)
Else
GetPlayer().RemoveItem(selectedForm, countID, True, BoxPotion)
EndIf
ElseIf selectedForm as Scroll
GetPlayer().RemoveItem(selectedForm, countID, True, BoxScroll)
ElseIf selectedForm as Ingredient
GetPlayer().RemoveItem(selectedForm, countID, True, BoxIngr)
ElseIf selectedForm as Book
GetPlayer().RemoveItem(selectedForm, countID, True, BoxBook)
ElseIf selectedForm as MiscObject
GetPlayer().RemoveItem(selectedForm, countID, True, BoxMisc)
EndIf
EndIf
Else
ShowMenu01()
EndIf
EndIf
EndEvent
Function ShowMenu01()
Int Button = CB_Message01.Show()
If Button == 0 ; Далее
ShowMenu02()
ElseIf Button == 1
BoxWeapon.Activate(GetPlayer())
ElseIf Button == 2
BoxArmor.Activate(GetPlayer())
ElseIf Button == 3
BoxPotion.Activate(GetPlayer())
ElseIf Button == 4
BoxScroll.Activate(GetPlayer())
ElseIf Button == 5 ; Отмена
Return
EndIf
EndFunction
Function ShowMenu02()
Int Button = CB_Message02.Show()
If Button == 0 ; Далее
ShowMenu03()
ElseIf Button == 1
BoxFood.Activate(GetPlayer())
ElseIf Button == 2
BoxIngr.Activate(GetPlayer())
ElseIf Button == 3
BoxBook.Activate(GetPlayer())
ElseIf Button == 5 ; Отмена
Return
EndIf
EndFunction
Function ShowMenu03()
Int Button = CB_Message03.Show()
If Button == 0 ; Отмена
Return
ElseIf Button == 1
BoxMisc.Activate(GetPlayer())
ElseIf Button == 2
BoxOre.Activate(GetPlayer())
ElseIf Button == 3
BoxAnim.Activate(GetPlayer())
ElseIf Button == 4
BoxGem.Activate(GetPlayer())
ElseIf Button == 5
BoxSoul.Activate(GetPlayer())
EndIf
EndFunction
В результате, мы имеем полноценный мод, предоставляющий бездонные хранилища для всех категорий объектов, с простым и удобным доступом. И хотя еще не реализована автосортировка, но простота и скорость добавления объектов "напрямую", по нажатию кнопки, без открытия хранилища, компенсирует ее отсутствие!
На этом этот шаг заканчиваю - сложно писать блог, используя теги по-памяти и без гарантии сохранения форматирования...
Продолжение здесь
1 Комментарий
Рекомендуемые комментарии
Для публикации сообщений создайте учётную запись или авторизуйтесь
Вы должны быть пользователем, чтобы оставить комментарий
Создать аккаунт
Зарегистрируйте новый аккаунт в нашем сообществе. Это очень просто!
Регистрация нового пользователяВойти
Уже есть аккаунт? Войти в систему.
Войти