Убран мёртвый код проигрывания видео; заготовка своей модели ножа
PlayBlackPortalVideoLegacy и BlackPortalVideoPath ниоткуда не вызывались с 2026-09-09, когда концовку заменили слайдами. Разборы Pause/PlayVideo и синтаксиса @modfolder перенесены в NoteFlashbackPatch - единственное место, где эти API ещё вызываются. Перекрёстные ссылки в FinalSlides поправлены, устаревшее упоминание StayVideoPath/ReturnVideoPath убрано. В items.xml у necroWpnBladeNecroKnife добавлена закомментированная строка Meshfile под будущий бандл Resources/necroknife - включать вместе с самим бандлом, не раньше. Там же снято старое сомнение про TintColor: ваниль сама тинтит тот же boneShivPrefab, значит механизм на оружии работает. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y3pwyLpTrwz41qBjyjzNSA
This commit is contained in:
co-authored by
Claude Opus 5
parent
6e1f42f053
commit
026e006c9c
@@ -44,7 +44,7 @@ namespace NecromancerTome
|
||||
/// ПАУЗА. Begin ставит GameManager.Instance.Pause(true) один раз на всю сцену и больше её не
|
||||
/// трогает: снимать паузу незачем, потому что любой выход отсюда ведёт в главное меню, а
|
||||
/// GameManager.Disconnect() зовёт Pause(false) внутри себя (см. комментарий в
|
||||
/// PortalStonePatch.ActivateBlackPortal). Как и вся остальная UI-часть этого мода, сцена
|
||||
/// FinishEnding). Как и вся остальная UI-часть этого мода, сцена
|
||||
/// рассчитана на локального игрока - Pause вообще работает только в одиночной игре, это
|
||||
/// ограничение самой ванили, а не мода.
|
||||
/// </summary>
|
||||
@@ -258,14 +258,12 @@ namespace NecromancerTome
|
||||
/// "Конец".
|
||||
///
|
||||
/// ВИДЕО ОТСЮДА УБРАНО 2026-09-09 по прямому указанию ("временно, убираем вообще видосы
|
||||
/// из финала"). Сам вызов XUiC_VideoPlayer.PlayVideo целиком сохранён в
|
||||
/// PortalStonePatch.PlayBlackPortalVideoLegacy - вернуть видео можно, не восстанавливая
|
||||
/// код по кускам.
|
||||
///
|
||||
/// Файлы Video/FinalStay.webm, FinalReturn.webm и BlackPortal.webm УДАЛЕНЫ ИЗ МОДА
|
||||
/// 2026-09-09 перед публикацией: все три были побайтовой копией ванильного
|
||||
/// из финала"). Файлы Video/FinalStay.webm, FinalReturn.webm и BlackPortal.webm тогда же
|
||||
/// удалены из мода перед публикацией: все три были побайтовой копией ванильного
|
||||
/// TFP_Intro.webm (заглушка для тестов), а раздавать чужой ассет игры в релизе нельзя.
|
||||
/// Настоящее видео класть под тем же именем.
|
||||
/// Мёртвый код проигрывания видео (PortalStonePatch.PlayBlackPortalVideoLegacy и
|
||||
/// константа с путём) убран 2026-09-10 - живой пример того же вызова, если видео
|
||||
/// понадобится вернуть, остался в NoteFlashbackPatch.cs.
|
||||
///
|
||||
/// Задержки и наезда здесь нет намеренно: смотреть на чёрный экран пять секунд незачем,
|
||||
/// текст показывается сразу.</summary>
|
||||
|
||||
@@ -7,10 +7,21 @@ namespace NecromancerTome
|
||||
/// <summary>
|
||||
/// Duke's note ("Записка от Дюка", item noteDuke01) - user request 2026-08-30: "в момент
|
||||
/// открытия записки, ставить игру на паузу и проигрывать флэшбек" (at the moment the note is
|
||||
/// opened, pause the game and play a flashback). Reuses the exact pause+video pipeline
|
||||
/// already built and tested for the Black Portal Stone (see PortalStonePatch.cs's
|
||||
/// ActivateBlackPortal - GameManager.Instance.Pause/XUiC_VideoPlayer.PlayVideo, both APIs
|
||||
/// decompiled there already, same reasoning applies unchanged here).
|
||||
/// opened, pause the game and play a flashback). Built on the pause+video pipeline first
|
||||
/// written for the Black Portal Stone; since the finale switched to text slides
|
||||
/// (FinalSlides) and its dead video code was removed 2026-09-10, this patch is the only
|
||||
/// place in the mod that still calls either API, so both write-ups live here now:
|
||||
/// - GameManager.Instance.Pause(bool) - decompiled GameManager.updatePauseState: sets
|
||||
/// Time.timeScale=0 for real, but ONLY takes effect in singleplayer (an SP-only check
|
||||
/// baked into vanilla itself, not a limitation added by this mod) - a deliberate,
|
||||
/// documented no-op in multiplayer rather than something silently broken.
|
||||
/// - XUiC_VideoPlayer.PlayVideo(xui, VideoData, skippable, onFinished) - opens the same
|
||||
/// fullscreen "VideoPlayer" window vanilla's own TFP intro/menu-background videos use.
|
||||
/// Decompiled XUiV_Video confirms video playback isn't gated by Time.timeScale, so it
|
||||
/// keeps playing correctly while paused. skippable=true (Cancel key) so a broken/
|
||||
/// missing video file can't soft-lock the player - XUiV_Video.OnVideoErrorReceived
|
||||
/// already auto-closes on a bad file on its own, this is just a second, player-facing
|
||||
/// way out.
|
||||
///
|
||||
/// FINDING THE RIGHT PATCH POINT: noteDuke01 has no custom C# class of its own - it's a
|
||||
/// plain Class="Eat" item (items.xml) whose entire "reading" experience is a vanilla trick:
|
||||
@@ -42,8 +53,9 @@ namespace NecromancerTome
|
||||
/// flashback -> read text -> confirm", rather than overlapping the video with the text box.
|
||||
///
|
||||
/// VIDEO FILE: Video/DukeNoteFlashback.mp4 - the user's real flashback clip (delivered
|
||||
/// 2026-08-30 as exch/flashbback.mp4), kept as .mp4 rather than renamed to .webm like the
|
||||
/// Black Portal placeholder: Unity's VideoPlayer component (confirmed by decompiling
|
||||
/// 2026-08-30 as exch/flashbback.mp4), and the only video the mod still ships. Kept as
|
||||
/// .mp4 rather than renamed to .webm like the since-deleted Black Portal placeholder:
|
||||
/// Unity's VideoPlayer component (confirmed by decompiling
|
||||
/// XUiV_Video - it wraps a plain UnityEngine.Video.VideoPlayer) natively decodes MP4/H.264 on
|
||||
/// Windows via Media Foundation, and re-labeling an actual MP4 container as .webm would just
|
||||
/// make it fail to decode (VP8/VP9 container expected, not H.264) - not decompiled/proven
|
||||
@@ -54,6 +66,11 @@ namespace NecromancerTome
|
||||
[HarmonyPatch(typeof(XUiC_MessageBoxWindowGroup), "ShowOkCancel")]
|
||||
public static class Patch_XUiC_MessageBoxWindowGroup_ShowOkCancel_NoteFlashback
|
||||
{
|
||||
/// <summary>"@modfolder(NecromancerTome):..." is the exact mod-relative path syntax
|
||||
/// XUiV_Video.startVideo resolves via ModManager.TryPatchModPathString (decompiled to
|
||||
/// confirm - looks for "@modfolder(<mod name>):" and substitutes the mod's real
|
||||
/// install path; "NecromancerTome" here is this mod's own ModInfo.xml Name, not its
|
||||
/// DisplayName).</summary>
|
||||
public const string NoteFlashbackVideoPath = "@modfolder(NecromancerTome):Video/DukeNoteFlashback.mp4";
|
||||
|
||||
/// <summary>Guards the re-entrant call this patch makes to the very method it patches
|
||||
|
||||
@@ -159,45 +159,23 @@ namespace NecromancerTome
|
||||
TeleportToBedroll(player);
|
||||
}
|
||||
|
||||
/// <summary>Black portal confirmation + fullscreen video, user request 2026-08-30
|
||||
/// ("диалоговое окно... вы уверены... Если Да, то игра останавливается и проигрывается
|
||||
/// видео"). Real APIs, both decompiled directly:
|
||||
/// - XUiC_MessageBoxWindowGroup.ShowCustom(xui, title, text, icon, setupCallback, ...) -
|
||||
/// the same generic Yes/No popup vanilla itself uses (its own delete-item/disconnect
|
||||
/// confirmations, etc). ShowOkCancel/ShowConfirmCancel exist too but hardcode their
|
||||
/// button caption keys ("xuiOk"/"xuiCancel"/"btnConfirm") - ShowCustom's
|
||||
/// _setupCallback is the only variant that lets the two buttons be captioned
|
||||
/// "xuiYes"/"xuiNo" directly (both are real, already-localized vanilla keys, confirmed
|
||||
/// against Data/Config/Localization.csv), matching the user's literal "да/нет"
|
||||
/// wording. Buttons[0]/[2] (not [1]) is the same slot pairing ShowOkCancel/
|
||||
/// ShowConfirmCancel themselves use internally - Buttons[1] is left unused, same as
|
||||
/// vanilla's own 2-button dialogs.
|
||||
/// - GameManager.Instance.Pause(bool) - decompiled GameManager.updatePauseState: sets
|
||||
/// Time.timeScale=0 for real, but ONLY takes effect in singleplayer (an SP-only check
|
||||
/// baked into vanilla itself, not a limitation added by this mod) - a deliberate,
|
||||
/// documented no-op in multiplayer rather than something silently broken.
|
||||
/// - XUiC_VideoPlayer.PlayVideo(xui, VideoData, skippable, onFinished) - opens the same
|
||||
/// fullscreen "VideoPlayer" window vanilla's own TFP intro/menu-background videos use.
|
||||
/// Decompiled XUiV_Video confirms video playback isn't gated by Time.timeScale, so it
|
||||
/// keeps playing correctly while paused. skippable=true (Cancel key) so a broken/
|
||||
/// missing video file can't soft-lock the player - XUiV_Video.OnVideoErrorReceived
|
||||
/// already auto-closes on a bad file on its own, this is just a second, player-facing
|
||||
/// way out.
|
||||
/// <summary>Black portal confirmation dialog, user request 2026-08-30
|
||||
/// ("диалоговое окно... вы уверены"). XUiC_MessageBoxWindowGroup.ShowCustom(xui, title,
|
||||
/// text, icon, setupCallback, ...) - the same generic Yes/No popup vanilla itself uses (its
|
||||
/// own delete-item/disconnect confirmations, etc), decompiled directly. ShowOkCancel/
|
||||
/// ShowConfirmCancel exist too but hardcode their button caption keys ("xuiOk"/"xuiCancel"/
|
||||
/// "btnConfirm") - ShowCustom's _setupCallback is the only variant that lets the two buttons
|
||||
/// be captioned "xuiYes"/"xuiNo" directly (both are real, already-localized vanilla keys,
|
||||
/// confirmed against Data/Config/Localization.csv), matching the user's literal "да/нет"
|
||||
/// wording. Buttons[0]/[2] (not [1]) is the same slot pairing ShowOkCancel/ShowConfirmCancel
|
||||
/// themselves use internally - Buttons[1] is left unused, same as vanilla's own 2-button
|
||||
/// dialogs.
|
||||
///
|
||||
/// VIDEO FILE: Video/BlackPortal.webm NO LONGER SHIPS WITH THE MOD. It used to be a
|
||||
/// byte-for-byte copy of vanilla's own TFP_Intro.webm (from
|
||||
/// 7DaysToDie_Data/StreamingAssets/Video/), placed there 2026-08-30 as a test stand-in
|
||||
/// ("Пока файл видео замени заглушкой") - deleted 2026-09-09 before the public release,
|
||||
/// since redistributing a game asset is not ours to do. This path is dead until a real
|
||||
/// video is dropped in under the same name; the method below is legacy anyway (the
|
||||
/// finale plays text epilogues now, see FinalSlides).
|
||||
/// "@modfolder(NecromancerTome):..." is the exact mod-relative path syntax
|
||||
/// XUiV_Video.startVideo resolves via ModManager.TryPatchModPathString (decompiled to
|
||||
/// confirm - looks for "@modfolder(<mod name>):" and substitutes the mod's real
|
||||
/// install path; "NecromancerTome" here is this mod's own ModInfo.xml Name, not its
|
||||
/// DisplayName).</summary>
|
||||
public const string BlackPortalVideoPath = "@modfolder(NecromancerTome):Video/BlackPortal.webm";
|
||||
|
||||
/// Второй половины прежнего сценария - паузы и полноэкранного видео - здесь больше нет:
|
||||
/// после "Да" управление уходит в FinalSlides (см. ActivateBlackPortal ниже), пауза живёт
|
||||
/// там, а видео из финала убрано 2026-09-09. Разбор GameManager.Instance.Pause и
|
||||
/// XUiC_VideoPlayer.PlayVideo переехал в NoteFlashbackPatch.cs - единственное место в моде,
|
||||
/// где обе эти ванильные API ещё вызываются.</summary>
|
||||
public static void ShowBlackPortalConfirmation(EntityPlayerLocal player)
|
||||
{
|
||||
LocalPlayerUI playerUI = LocalPlayerUI.GetUIForPlayer(player);
|
||||
@@ -220,55 +198,18 @@ namespace NecromancerTome
|
||||
}
|
||||
|
||||
/// <summary>ЗАМЕНЕНО 2026-09-09: раньше отсюда сразу стартовало полноэкранное видео
|
||||
/// (BlackPortalVideoPath), теперь запускается финальная сцена из шести слайдов с текстом
|
||||
/// (Video/BlackPortal.webm), теперь запускается финальная сцена из шести слайдов с текстом
|
||||
/// - FinalSlides.Begin. Причина в BACKLOG.md ("концовка серией диалоговых окон вместо
|
||||
/// видео"): видео не локализуется, а текст слайдов идёт обычной строкой через
|
||||
/// Localization.csv. Пауза и выход в главное меню никуда не делись - и то и другое
|
||||
/// теперь живёт внутри FinalSlides, а видео осталось финальным аккордом ПОСЛЕ выбора
|
||||
/// концовки на последнем слайде.
|
||||
///
|
||||
/// Всё, что описано в комментарии к BlackPortalVideoPath выше, по-прежнему верно и
|
||||
/// применяется - просто к двум новым файлам (FinalSlides.StayVideoPath /
|
||||
/// ReturnVideoPath) вместо одного. Сама константа BlackPortalVideoPath больше не
|
||||
/// используется и оставлена только как документация к разбору "@modfolder(...)" и
|
||||
/// XUiC_VideoPlayer.PlayVideo, на который FinalSlides ссылается.</summary>
|
||||
/// теперь живёт внутри FinalSlides. Видео из концовки убрано целиком 2026-09-09 -
|
||||
/// ни здесь, ни в FinalSlides его больше нет.</summary>
|
||||
public static void ActivateBlackPortal(EntityPlayerLocal player)
|
||||
{
|
||||
Debug.Log("[NecromancerTome] PortalStonePatch: black portal confirmed by owner=" + player.entityId + ", handing over to FinalSlides");
|
||||
FinalSlides.Begin(player);
|
||||
}
|
||||
|
||||
/// <summary>Прежняя концовка "сразу видео, потом главное меню". Больше ниоткуда не
|
||||
/// вызывается (см. ActivateBlackPortal выше) - оставлена целиком, потому что весь разбор
|
||||
/// Pause/PlayVideo/Disconnect в её комментариях остаётся актуальным и на неё ссылается
|
||||
/// FinalSlides. Удалять при следующей уборке, если так и не понадобится.</summary>
|
||||
public static void PlayBlackPortalVideoLegacy(EntityPlayerLocal player)
|
||||
{
|
||||
Debug.Log("[NecromancerTome] PortalStonePatch: black portal confirmed by owner=" + player.entityId + ", pausing + playing video");
|
||||
GameManager.Instance.Pause(true);
|
||||
LocalPlayerUI playerUI = LocalPlayerUI.GetUIForPlayer(player);
|
||||
VideoData videoData = new VideoData { url = BlackPortalVideoPath };
|
||||
XUiC_VideoPlayer.PlayVideo(playerUI.xui, videoData, true, delegate(bool skipped)
|
||||
{
|
||||
// EXIT TO MAIN MENU after the video, user request 2026-08-30 ("После видео нужно
|
||||
// выходить из игры в главное меню") - fires whether the video played to the end
|
||||
// or was skipped (Cancel key / a bad file), same as any other "the video is over"
|
||||
// outcome. GameManager.Instance.Disconnect() is not a guess - it's the EXACT same
|
||||
// call the real in-game ESC menu's own "Exit to Main Menu" button uses
|
||||
// (decompiled XUiC_InGameMenuWindow.exitGame/BtnExit_OnPressed to confirm: it's a
|
||||
// thin wrapper straight to this method). Handles everything a clean exit needs by
|
||||
// itself - closes modal windows, un-pauses (calls Pause(false) internally, so no
|
||||
// separate unpause call needed here), saves/shuts down the local server, and
|
||||
// returns to XUiC_MainMenu - not reinventing any of that by hand. Replaces the
|
||||
// earlier "thrownStonePortalBlackNotBound" tooltip placeholder entirely: with a
|
||||
// real exit-to-menu ending, staying in-game and showing a tooltip no longer makes
|
||||
// sense (BACKLOG.md item 6's "destination not decided" placeholder is now this
|
||||
// exit itself, not a tooltip).
|
||||
Debug.Log("[NecromancerTome] PortalStonePatch: black portal video finished (skipped=" + skipped + "), exiting to main menu");
|
||||
GameManager.Instance.Disconnect();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>BedrollPos comes from EntityPlayer.PersistentPlayerData (decompiled - reads
|
||||
/// GameManager.Instance.persistentPlayers.GetPlayerDataFromEntityID(entityId)), the same
|
||||
/// field the game's own respawn-at-bedroll flow reads (PersistentPlayerData.BedrollPos /
|
||||
|
||||
Reference in New Issue
Block a user