4 005 [GA] BattleFrame Разработчик, Коллекционер 2 853 публикации 23 434 боя Жалоба #1 Опубликовано: 25 мар 2024, 09:58:46 В данной теме вы можете обсудить и задать возникшие вопросы по созданию модификаций и руководствам на фреймворке Unbound 2. Рассказать о публикации Ссылка на публикацию
0 sddo Участник 3 публикации 116 боёв Жалоба #2 Опубликовано: 13 май 2024, 17:39:18 Доброго времени суток. Решил поизучать как делать моды для игры. Читаю мануал. Пока не очень все понятно, если честно, но, пыхчу. Вопрос: В мане есть $datahub объект. Как можно узнать список всех его методов и полей? Не нашел инфы, если честно :( Рассказать о публикации Ссылка на публикацию
5 070 [LESTA] MatroseFuchs Разработчик 1 323 публикации 7 426 боёв Жалоба #3 Опубликовано: 14 май 2024, 06:25:27 В 13.05.2024 в 17:39:18 пользователь sddo сказал: Доброго времени суток. Решил поизучать как делать моды для игры. Читаю мануал. Пока не очень все понятно, если честно, но, пыхчу. Вопрос: В мане есть $datahub объект. Как можно узнать список всех его методов и полей? Не нашел инфы, если честно :( Добрый день. Основные методы работы с датахабом можно посмотреть в примерах или в файлах разметки интерфейса в ресурсах клиента. Чтобы упростить этот процесс мы добавим эту информацию с примерами в ближайшее время. 1 Рассказать о публикации Ссылка на публикацию
0 sddo Участник 3 публикации 116 боёв Жалоба #4 Опубликовано: 14 май 2024, 12:11:53 (изменено) Доброго времени суток :) Я правильно понимаю, что element верхнеуровневый. Для примера изучаю мод и фак более опытных разрабов. Там заметил что element можно переопределить. Например в моде Battle expert переопределяют DangerItemContainer. Я решил попробовать и переопределить ButtonAccount из главного меню(прочитав статью про распаковку ресов и распаковав элемент для изучения). Как заметил для этого достаточно просто скопировать код элемента в файл мода. (возможно я не верно понял, потому что не понимаю как происходит инициализация элементов интерфейса при запуске. происходит сравнение DO и они объединяются?) Но меня постигла неудача, я изменил участок чтобы цвет шрифта ника был желтым(цвет который красит ник, если у тебя премиум), но, при загрузки ничего не произошло. Я не могу менять эти элементы или просто не так что-то делаю? вот DO который я изменил : Цитата (tf (name = 'label_button_account') (class $TextDefault13NM) (style (marginTop = "S") (wordWrap = false) (bind textColor "isPremiumAccount ? SC.Ui_styles.SERVICE_COLORS.RED : SC.Ui_styles.SERVICE_COLORS.YELLOW") (bind alpha "subTextAlpha" watch=false) ) (bind text "accountText") (macro DEFAULT_CONTROL_STATE_ANIMATION_ALPHA _trigger = "state" _alpha = "subTextAlpha" ) ) сам мод расположил в директории "Korabli\bin\8275422\res_mods\gui\unbound2\vkr\learn_1\!vkr_learn_1.unbound" Изменено 14 май 2024, 12:29:02 пользователем sddo Рассказать о публикации Ссылка на публикацию
4 005 [GA] BattleFrame Разработчик, Коллекционер 2 853 публикации 23 434 боя Жалоба #5 Опубликовано: 14 май 2024, 13:16:08 В 14.05.2024 в 12:11:53 пользователь sddo сказал: Доброго времени суток :) Я правильно понимаю, что element верхнеуровневый. Для примера изучаю мод и фак более опытных разрабов. Там заметил что element можно переопределить. Например в моде Battle expert переопределяют DangerItemContainer. Я решил попробовать и переопределить ButtonAccount из главного меню(прочитав статью про распаковку ресов и распаковав элемент для изучения). Как заметил для этого достаточно просто скопировать код элемента в файл мода. (возможно я не верно понял, потому что не понимаю как происходит инициализация элементов интерфейса при запуске. происходит сравнение DO и они объединяются?) Но меня постигла неудача, я изменил участок чтобы цвет шрифта ника был желтым(цвет который красит ник, если у тебя премиум), но, при загрузки ничего не произошло. Я не могу менять эти элементы или просто не так что-то делаю? вот DO который я изменил : Не могли бы вы приложить файл мода, который у вас получился? Да, вам необходимо скопировать весь блок "def element" в файл мода и тогда он может быть изменён. Никакого объединения не происходит, а логика довольно проста: работать будет тот элемент, который быстрее загрузился. А загрузится быстрее тот, который находится в файле идущем раньше по алфавиту. Это значит что элемент из файла alpha.unboud загрузится быстрее чем из delta.unboud Причем это правило работает и на путь к файлу! В 14.05.2024 в 12:11:53 пользователь sddo сказал: сам мод расположил в директории "Korabli\bin\8275422\res_mods\gui\unbound2\vkr\learn_1\!vkr_learn_1.unbound" Вам необходимо переименовать папку vkr в !vkr 1 Рассказать о публикации Ссылка на публикацию
0 sddo Участник 3 публикации 116 боёв Жалоба #6 Опубликовано: 14 май 2024, 13:25:51 В 14.05.2024 в 13:16:08 пользователь BattleFrame сказал: Не могли бы вы приложить файл мода, который у вас получился? Да, вам необходимо скопировать весь блок "def element" в файл мода и тогда он может быть изменён. Никакого объединения не происходит, а логика довольно проста: работать будет тот элемент, который быстрее загрузился. А загрузится быстрее тот, который находится в файле идущем раньше по алфавиту. Это значит что элемент из файла alpha.unboud загрузится быстрее чем из delta.unboud Причем это правило работает и на путь к файлу! Вам необходимо переименовать папку vkr в !vkr Вот мой "мод" :) я просто скопировал весь элемент и поменял WHITE на YELLOW. Показать содержимое Цитата (def element ButtonAccount () (scope (event evAccountInfotipItemClicked) (macro MOUSE_HANDLER_SCOPE) (macro PULL_SELF_PLAYER_SCOPE) (var accountInfotipIsVisible:bool = "false") (var abuseStatus:number = "selfPlayerEntity ? selfPlayerEntity.accountInfo.abuseStatus : 0" (event "selfPlayerEntity.accountInfo.evAbuseStatusChanged")) (var accountLevel:number = "selfPlayerEntity ? selfPlayerEntity.accountLevel.level : 0" (event "selfPlayerEntity.accountLevel.evLevelChanged")) (var rank:number = "selfPlayerEntity ? selfPlayerEntity.accountRank.rank : 0" (event "selfPlayerEntity.accountRank.evRankChanged")) (var league:number = "selfPlayerEntity ? selfPlayerEntity.accountRank.league : 0" (event "selfPlayerEntity.accountRank.evRankChanged")) (var realmConstantsEntity:gfx = "$datahub.getSingleEntity(CC.realmConstants)") (var realmConstantsComponent:gfx = "realmConstantsEntity ? realmConstantsEntity.realmConstants : null") (var isInviteRefferalFriendUIAvailable:bool = "realmConstantsComponent ? realmConstantsComponent.isInviteRefferalFriendUIAvailable : false") (var resourceWatcher:gfx = "$datahub.getFirstWatcher(CC.accountResource)") (var resourceEntity:gfx = "resourceWatcher.entity" (event "resourceWatcher.event")) (var resourceComponent:gfx = "resourceEntity ? resourceEntity.accountResource : null") (var premiumType:number = "resourceComponent ? resourceComponent.activePremiumType : 0" (event "resourceComponent.evActivePremiumTypeChanged")) (var premBefore:number = "resourceComponent ? resourceComponent.premBefore : 0" (event "resourceComponent.evChangedPrem")) (var wowsPremBefore:number = "resourceComponent ? resourceComponent.wowsPremBefore : 0" (event "resourceComponent.evChangedPrem")) (var hasReferralPoints:bool = "resourceComponent ? resourceComponent.hasReferralPoints : false" (event "resourceComponent.evChangedHasReferralPoints")) (var isPremiumAccount:bool = "premiumType != SC.Common.PREMIUM_TYPE.NONE") (var activePremTime:number = "premiumType == SC.Common.PREMIUM_TYPE.WOWS ? wowsPremBefore : premBefore") (macro SERVER_TIME_SCOPE) (var timeLeft:number = "floor(activePremTime - serverTime)") (var timeLeftFormatted:str = "formatTime(timeLeft, 'HIGHESTDAYS')") (var accountText:str = "isPremiumAccount ? tr('IDS_ACCOUNT_PREMIUM') + ' ' + timeLeftFormatted : 'IDS_ACCOUNT_DEFAULT'") (var isSyncedWithWallet:bool = "resourceComponent ? resourceComponent.isSyncedWithWallet : false" (event "resourceComponent.evChangedIsSyncedWithWallet")) (var walletAvailable:bool = "resourceComponent ? resourceComponent.walletStatus : false" (event "resourceComponent.evChangedWalletStatus")) (var showWGWalletWarning:bool = "!isSyncedWithWallet || !walletAvailable") (var isAbuseStatusConfirmed:bool = "abuseStatus > 0") (macro FEATURES "23") (var referralCollection:gfx = "$datahub.getCollection(CC.referral)") (var referralCollectionItems:array = "referralCollection ? referralCollection.items : []" (event "referralCollection.evAdded") (event "referralCollection.evRemoved")) (var isRefSysParticipant:bool = "referralCollectionItems.length > 0") (var accountCompletionEntity:gfx = "$datahub.getSingleEntity(CC.accountCompletion)") (var isAccountCompletionAvailable:bool = "accountCompletionEntity ? accountCompletionEntity.accountCompletion.isAvailable : false") (var steamLoginEntity:gfx = "$datahub.getSingleEntity(CC.steamLoginData)") (var steamLoginEmailBound:bool = "steamLoginEntity ? steamLoginEntity.steamLoginData.emailBind : false" (event "steamLoginEntity.steamLoginData.evUpdate")) (var isAccountNotCompletedMarkerVisible:bool = "isAccountCompletionAvailable && !steamLoginEmailBound") (var userTaskEntity:gfx = "$datahub.getSingleEntity(CC.userTask)") (var userTaskComponent:gfx = "userTaskEntity ? userTaskEntity.userTask : null") (var currentUserTaskFlags:array = "userTaskComponent ? userTaskComponent.flags : []" (event "userTaskComponent.evFlagChanged")) (var isReferralMenuItemVisible:bool = "isInviteRefferalFriendUIAvailable && (accountLevel >= SC.Ui_common.AL_MENU_FEATURES_VISIBILITY.REFERRAL || isRefSysParticipant)") (var isReferralNotSeen:bool = "isReferralMenuItemVisible && currentUserTaskFlags[BINARY_SHIFT_MAP[SC.Common.USER_TASKS_FLAGS.CONTROL_SEEN_PLAYTOGETHER]] == 0") (var isBuyPremiumNotSeen:bool = " currentUserTaskFlags[BINARY_SHIFT_MAP[SC.Common.USER_TASKS_FLAGS.KNOWS_ABOUT_WOWS_PREM]] == 0 && accountLevel >= SC.Ui_common.AL_MENU_FEATURES_VISIBILITY.BUY_PREMIUM") (var isWarehouseNotSeen:bool = "feature_23 == 'new'") (var isMarkerNewVisible:bool = "isAccountNotCompletedMarkerVisible || isReferralNotSeen || isBuyPremiumNotSeen || isWarehouseNotSeen") (var isRefPointsRewardVisible:bool = "hasReferralPoints && !isMarkerNewVisible") (var maxAccountSublabelAlpha:number = "isPremiumAccount ? 1 : TA") (var state:number = " accountInfotipIsVisible ? SC.Ui_styles.BUTTON_STATE.SELECTED : mouseDown ? SC.Ui_styles.BUTTON_STATE.DOWN : rollOver ? SC.Ui_styles.BUTTON_STATE.OVER : SC.Ui_styles.BUTTON_STATE.UP") (var mainLabelAlpha:number = " abuseStatus == SC.Common.ABUSE_STATUS.CONFIRMED || abuseStatus == SC.Common.ABUSE_STATUS.SUSPECT || isPremiumAccount ? PORT_HEADER_MAIN_TEXT_COLORIZED_ALPHA[state] : PORT_HEADER_MAIN_TEXT_ALPHA[state]") (var subTextAlpha:number = "isPremiumAccount ? PORT_HEADER_SUBTEXT_COLORIZED_ALPHA[state] : PORT_HEADER_SUBTEXT_ALPHA[state]") (var ctRollOver:dict = "{ redMultiplier: 1, greenMultiplier: 1, blueMultiplier: 1, alphaMultiplier: 1, redOffset: 15, greenOffset: 15, blueOffset: 15, alphaOffset: 0 }") (var ctDown:dict = " { redMultiplier: 1, greenMultiplier: 1, blueMultiplier: 1, alphaMultiplier: 1, redOffset: -30, greenOffset: -30, blueOffset: -30, alphaOffset: 0 }") (macro CALCULATE_PORT_HEADER_ELEM_SIDE_PADDING) (var rankIconWidthWithMargins:number = "rank > 0 ? ACCOUNT_BUTTON_ELEMS_WIDTH.RANK_ICON + XS : 0") (var referralActiveIconWidthWithMargins:number = "isRefPointsRewardVisible ? ACCOUNT_BUTTON_ELEMS_WIDTH.REFERRAL_ACTIVE_ICON + XXS + XXS : 0") (var maxTotalAccountButtonWidth:number = "(stageWidth / 2) - ((DOCK_HEADER_ELEMS_WIDTH.SETTINGS + PORT_HEADER_SETTINGS_AND_DOGTAG_GAP) + DOCK_HEADER_ELEMS_WIDTH.DOGTAG + (DOCK_HEADER_ELEMS_WIDTH.PORT_LARGEST + S) + (DOCK_HEADER_ELEMS_WIDTH.WANT_IN_DIVISION + S) + (DOCK_HEADER_ELEMS_WIDTH.START_BATTLE_BTN / 2) + PORT_HEADER_START_BATTLE_BTN_SIDE_MARGIN)") (var minTotalAccountButtonWidth:number = "111 + (2 * PORT_HEADER_CONTROL_DEFAULT_PADDING) + (ACCOUNT_BUTTON_ELEMS_WIDTH.ARROW + SXS)") (var accountButtonWidth:number = "maxTotalAccountButtonWidth < minTotalAccountButtonWidth ? minTotalAccountButtonWidth : maxTotalAccountButtonWidth") (var sideMarginFor17NMText:number = "3") (var maxNicknameTextWidth:number = "accountButtonWidth - ((2 * PORT_HEADER_CONTROL_DEFAULT_PADDING) + (ACCOUNT_BUTTON_ELEMS_WIDTH.ARROW + SXS) + rankIconWidthWithMargins + referralActiveIconWidthWithMargins) + (2 * sideMarginFor17NMText)") (var webStorageIntroNewWatcher:gfx = "$datahub.getPrimWatcher(CC.newGuidingTip, SC.Context_guiding_tip.TIP_TYPE.WEB_STORAGE_INTRO)") (var webStorageIntroRepeatNewWatcher:gfx = "$datahub.getPrimWatcher(CC.newGuidingTip, SC.Context_guiding_tip.TIP_TYPE.WEB_STORAGE_INTRO_REPEAT)") (var inviteFriendNewWatcher:gfx = "$datahub.getPrimWatcher(CC.newGuidingTip, SC.Context_guiding_tip.TIP_TYPE.INVITE_DOCK_USER_MENU)") (var webStorageIntroNewTip:gfx = "webStorageIntroNewWatcher ? webStorageIntroNewWatcher.entity : null" (event "webStorageIntroNewWatcher.event")) (var webStorageIntroRepeatNewTip:gfx = "webStorageIntroRepeatNewWatcher ? webStorageIntroRepeatNewWatcher.entity : null" (event "webStorageIntroRepeatNewWatcher.event")) (var inviteFriendNewTip:gfx = "inviteFriendNewWatcher ? inviteFriendNewWatcher.entity : null" (event "inviteFriendNewWatcher.event")) (var isWebStorageIntroNewTipActive:bool = "webStorageIntroNewTip ? webStorageIntroNewTip.newGuidingTip.isActive : false" (event "webStorageIntroNewTip.newGuidingTip.evChanged")) (var isWebStorageIntroRepeatNewTipActive:bool = "webStorageIntroRepeatNewTip ? webStorageIntroRepeatNewTip.newGuidingTip.isActive : false" (event "webStorageIntroRepeatNewTip.newGuidingTip.evChanged")) (var isInviteFriendNewTipActive:bool = "inviteFriendNewTip ? inviteFriendNewTip.newGuidingTip.isActive : false" (event "inviteFriendNewTip.newGuidingTip.evChanged")) (var chainId:number = " isWebStorageIntroNewTipActive ? SC.Context_guiding_tip.TIP_CHAIN_ID.WEB_STORAGE : isWebStorageIntroRepeatNewTipActive ? SC.Context_guiding_tip.TIP_CHAIN_ID.WEB_STORAGE_REPEAT : isInviteFriendNewTipActive ? SC.Context_guiding_tip.TIP_CHAIN_ID.INVITE_FRIEND : SC.Context_guiding_tip.TIP_CHAIN_ID.NONE") (var tipId:number = " isWebStorageIntroNewTipActive ? SC.Context_guiding_tip.TIP_TYPE.WEB_STORAGE_INTRO : isWebStorageIntroRepeatNewTipActive ? SC.Context_guiding_tip.TIP_TYPE.WEB_STORAGE_INTRO_REPEAT : isInviteFriendNewTipActive ? SC.Context_guiding_tip.TIP_TYPE.INVITE_DOCK_USER_MENU : SC.Context_guiding_tip.TIP_TYPE.NONE") (var isNewTipVisible:bool = "!accountInfotipIsVisible && tipId != SC.Context_guiding_tip.TIP_TYPE.NONE") ) (hblock (style (hitTest = false) (align = "middle") (height = 100%) ) (block (style (align = "middle") (height = 100%) (marginRight = "SXS") ) (hblock (block (bind visible "rank > 0") (bind colorTransform " mouseDown ? ctDown : rollOver ? ctRollOver : CT_NONE") (style (marginTop = -3px) (marginBottom = "-XS") (marginLeft = -1px) (marginRight = "XS") ) (controller $Instance renderer='IconRankSmall' (bind enabled "rank > 0") (args _league = "league" _rank = "rank" ) ) ) (block (tf (name = 'playerName_button_account') (class $TextDefaultBold17NM) (style (bind maxWidth "maxNicknameTextWidth") (wordWrap = false) (elideMode = true) (bind textColor " abuseStatus == SC.Common.ABUSE_STATUS.CONFIRMED ? SC.Ui_styles.SERVICE_COLORS.RED : abuseStatus == SC.Common.ABUSE_STATUS.SUSPECT ? SC.Ui_styles.SERVICE_COLORS.PINK : isPremiumAccount ? SC.Ui_styles.SERVICE_COLORS.YELLOW : SC.Ui_styles.SERVICE_COLORS.YELLOW") (bind alpha "mainLabelAlpha" watch=false) ) (bind text "selfPlayerName") (macro DEFAULT_CONTROL_STATE_ANIMATION_ALPHA _trigger = "state" _alpha = "mainLabelAlpha" ) ) (block (macro DEFAULT_CONTROL_MARKER_ANIMATION "isMarkerNewVisible") (style (position = "absolute") (right = -47px) (top = "-S") (hitTest = false) ) (element MarkerNew) ) ) (block (bind visible "isRefPointsRewardVisible") (style (marginLeft = "XXL") (marginRight = "XXS") (width = 24px) (height = 8px) ) (controller $Instance renderer='MarkerNewRewardsAnimate' (bind enabled "isRefPointsRewardVisible") (args _iconReward = 'url:../service_kit/account_menu/referral_active.png' ) ) ) ) (tf (name = 'label_button_account') (class $TextDefault13NM) (style (marginTop = "S") (wordWrap = false) (bind textColor "isPremiumAccount ? SC.Ui_styles.SERVICE_COLORS.RED : SC.Ui_styles.SERVICE_COLORS.YELLOW") (bind alpha "subTextAlpha" watch=false) ) (bind text "accountText") (macro DEFAULT_CONTROL_STATE_ANIMATION_ALPHA _trigger = "state" _alpha = "subTextAlpha" ) ) ) (element DockHeaderControlArrow _state = "state" ) ) ) !vkr_learn2.rar upd: Спасибо! переименование папки помогло. Символ поднял ее в очереди загрузки. Спасибо за разъяснение!) 1 Рассказать о публикации Ссылка на публикацию
2 529 [KKZ50] ru1719 Участник 2 842 публикации 22 330 боёв Жалоба #7 Опубликовано: 16 май 2024, 07:10:41 Господа мододелы, напомню свою просьбу: напишите и разберите пример простой программки "хелловорлд" -- напечатать простое текстовое сообщение в боевом интерфейсе, скажем, о текущей скорости корабля. Для себя вижу это первым шагом в благородном деле модов. Рассказать о публикации Ссылка на публикацию
4 005 [GA] BattleFrame Разработчик, Коллекционер 2 853 публикации 23 434 боя Жалоба #8 Опубликовано: 16 май 2024, 07:29:23 В 16.05.2024 в 07:10:41 пользователь ru1719 сказал: Господа мододелы, напомню свою просьбу: напишите и разберите пример простой программки "хелловорлд" -- напечатать простое текстовое сообщение в боевом интерфейсе, скажем, о текущей скорости корабля. Для себя вижу это первым шагом в благородном деле модов. [FAQ] Пример поиска файлов для модифицирования в Unbound 2 [UB2] Анимация элементов Абсолютно идентичный порядок действий, только вместо квадратика будет текст) В случае с UB2 "хелловорлд" является скорее уже второй ступенью, сначала нужно понять как находить файлы для изменений и как размещать в них свои элементы Рассказать о публикации Ссылка на публикацию
2 529 [KKZ50] ru1719 Участник 2 842 публикации 22 330 боёв Жалоба #9 Опубликовано: 16 май 2024, 07:39:59 В 16.05.2024 в 07:29:23 пользователь BattleFrame сказал: В случае с UB2 "хелловорлд" является скорее уже второй ступенью Хорошо, но я привык по-старому: программа=мод "хелловорлд". Ставлю, запускаю, вижу, разбираю что откуда и куда берётся, модифицирую как мне нужно, задаю доп. вопросы. Таким вижу процесс обучения с нуля. Подсмотрел в книге Керниган-Ричи "язык С". (которую, кстати, переводил мой знакомый в качестве шабашки ))). Рассказать о публикации Ссылка на публикацию
4 005 [GA] BattleFrame Разработчик, Коллекционер 2 853 публикации 23 434 боя Жалоба #10 Опубликовано: 16 май 2024, 07:45:19 В 16.05.2024 в 07:39:59 пользователь ru1719 сказал: Хорошо, но я привык по-старому: программа=мод "хелловорлд". Ставлю, запускаю, вижу, разбираю что откуда и куда берётся, модифицирую как мне нужно, задаю доп. вопросы. Таким вижу процесс обучения с нуля. Подсмотрел в книге Керниган-Ричи "язык С". (которую, кстати, переводил мой знакомый в качестве шабашки ))). Ну для начала, мод != программа :) Unbound2 интерфейс разделён на части, которые лежат в разных файлах. Нет такого чтобы на экран добавить "хелловорлд" и просто перемещать его в любое место. Его всё равно придётся прописать в один из элементов интерфейса у которого в свою очередь есть определённая область (грубо говоря вы не сможете в элемент миникарты адекватно добавить что-то, что должно будет отображаться по центру экрана. Рассказать о публикации Ссылка на публикацию
2 529 [KKZ50] ru1719 Участник 2 842 публикации 22 330 боёв Жалоба #11 Опубликовано: 16 май 2024, 07:50:35 В 16.05.2024 в 07:45:19 пользователь BattleFrame сказал: . Нет такого чтобы на экран добавить "хелловорлд" и просто перемещать его в любое место. Его всё равно придётся прописать в один из элементов интерфейса у которого в свою очередь есть определённая область (грубо говоря вы не сможете в элемент миникарты адекватно добавить что-то, что должно будет отображаться по центру экрана. Вот! это уже содержательная часть обучающего поста "как написать свой мод". Абсолютно без иронии. Людям со стороны ведь это непонятно! Поэтому нужно пособие для знающих только С (а лучше только Фортран ))), как написать простой мод с нуля. 2 Рассказать о публикации Ссылка на публикацию