WorldMgr/zh: Difference between revisions

From ZeldaMods (Breath of the Wild)
Jump to navigation Jump to search
(Created page with "=== 日夜標籤 === 這些標籤讓程式的其他部分可以用有語義的方式檢查現在是早上還是晚上等等。 From 00:00 to 06:00 (closed interval) and from...")
No edit summary
Line 142: Line 142:


* 如果沒辦法出現血月(下面有列原因),血月計時器會被設在 2880.0。
* 如果沒辦法出現血月(下面有列原因),血月計時器會被設在 2880.0。
* 如果血月可以出現,呼叫 Demo011_0(又到了紅月出現的時刻,林克你要小心) 然後血月計時器歸零。
* 如果血月可以出現,播放 [https://eventviewer.zeldamods.org/viewer.html?data=/d/Demo011_0.json&params=1 Demo011_0](又到了紅月出現的時刻,林克你要小心), 然後血月計時器歸零。


'''「好久沒有血月了」''':
'''「好久沒有血月了」''':

Revision as of 23:41, 10 May 2020

Other languages:
WorldMgr
Subsystem
Official name Yes
Description 控制世界的状态(时间、血月、气候、天气、等等。)
Init function Switch 1.5.0: 00000071010F2920
Wii U 1.5.0: ???
Debug only No

World Manager (WorldMgr) 是游戏里的一个子系统。 它控制时间、血月、气候、天气、雾、风、闪电、云、山林霸主的出现等等。

这个子系统很大/复杂,它的功能被切成九个部分。

WorldMgr

小主管

小主管 (Sub-managers) 由 WorldMgr::init (0x71010F43C0) 生成,and inserted into a pointer array (@WorldMgr+0x5c0). 注意以下名称不是官方名称。

小主管及其编号 (ID)
编号 负责内容
0 TimeMgr: 时间、血月、山林霸主
1 CloudPrMgr: 程序化生成的云
2 ShootingStarMgr: 黄色的流星跟红色的异度神剑2流星(1.3.3版及其后)。
3 WeatherMgr: Handles "rain splash" and 气候、天气
4 TempMgr: 温度[check].
5 ?
6 SkyMgr: 天空、雾[check]. Holds the configuration for all EnvPalettes, EnvAttributes, WeatherInfluences, Remains palettes, Indoor palettes and dungeon fogs.
7 DofMgr: Handles depth of field[check]. Holds depth of field related parameters.
8 ?

气候

WorldMgr 本身(而不是小主管)负责处理气候那一类的事情。 气候显然是由玩家所在的位置决定的(在火山很热、在雪山很冷), 有趣的是,它是用摄影机所在的位置而不是林克所在的位置来决定气候的。

TimeMgr

TimeMgr 管理所有跟时间有关的事情,例如血月何时出现,山林霸主何时出现。

游戏内时间(小时跟分钟)是一个 [0.0, 360.0] 范围内的浮点数。 0.0 跟 360 代表子夜,90 大约是早晨,180.0 代表正午,依此类推。

TimeMgr::init

(init 代表初始化设定)

  • 游戏内时间令为 78.75,早上 05:15 的意思。
  • Time for TotS environment is set to 78.75 (05:15) as well.
  • "Bloody Moon end reserve timer" is set to 0.(这个计时器不是用来倒数血月何时出现的那个,下面会详述。)

TimeMgr::reset

This is called whenever a stage is unloaded (essentially every time the loading screen is shown). 意思是凡是读档就会呼叫这个函数。

  • 血月相关检查会被延后。
  • 山林霸主的 flag 会被设为 false,意思是不要出现。

TimeMgr::calc

这个函数每帧呼叫一次。

  • (If field 0x14A is set to 99, WM_BloodyDay is set to true. AIDef:Action/SetBloodyMoonEnv uses this to force a Blood Moon to be scheduled. This feature appears to be unused.)(好像是没用到的功能。)
  • 如果某两个过场动画 Demo103_0 and Demo997_0 都还没播过的话,时间会被固定在 78.75(早上 05:15)。
    • 那两个过场动画,前一个是林克走出复苏神庙后环顾海拉鲁,后一个没有使用。
  • 如果 AIDef:Action/AdvanceTime 或是其他什么东西强制把时间定在某个值的话,那时间就会更新。
  • #子夜检查
  • 更新时间:有几种更新的模式,大部分的时候是用模式 0。
模式 更新方式
0 如果 Demo103_0 或 Demo997_0 播过,而且不是在过场动画里的话:
  • 游戏内时间(那个符点数)会增加“0.0083333 * 帧数”,本游戏一秒三十帧,所以游戏里的一分钟是现实生活中的一小时。
  • 如果游戏内时间 ≥ 360.0,也就是完整的一天已经过完了,那就减掉 360,然后执行子夜检查(下面详述)。
  • If FindDungeon_Activated is false (if the player hasn't received the The Isolated Plateau quest) and if the current time is >= 165.0 (11:00), the time is forcefully set to 11:00. Effectively, this means that time will not get past 11:00 until the Great Plateau Tower is activated and the Old Man cutscene is triggered. 整句的意思是,游戏从 5:15 开始跑,如果到 11:00 时玩家还没启动初始之塔而且爬下来的话,游戏时间会固定在早上 11:00。
  • 血月计时器也会增加(增加跟游戏内时间相同的量)。
1, 13, 35 Freeze time to 04:00 把时间固定在 04:00
2, 14 Freeze time to 05:00
3, 16, 36 Freeze time to 07:00
4, 19, 37 Freeze time to 10:00
5, 26, 39 Freeze time to 17:00
6, 28, 40 Freeze time to 19:00
7, 30, 41 Freeze time to 21:00
8, 11 Freeze time to 02:00
9, 42 Freeze time to 00:00
10 Freeze time to 01:00
12 Freeze time to 03:00
15 Freeze time to 06:00
17 Freeze time to 08:00
18 Freeze time to 09:00
20 Freeze time to 11:00
21 Freeze time to 12:00
22, 38 Freeze time to 13:00
23 Freeze time to 14:00
24 Freeze time to 15:00
25 Freeze time to 16:00
27 Freeze time to 18:00
29 Freeze time to 20:00
31 Freeze time to 22:00
32 Freeze time to 23:00
34
  • 游戏内时间增加“0.0083333 * 帧数”。
  • 如果游戏内时间 >= 360.0, 也就是完整的一天已经过完了,那就减掉 360。

附注: 这个模式跟模式 0 不一样的地方在于血月计时器既不更新也不检查。

  • 更新 #日夜标签,更新 #晨午暮夜标签
  • If the "Bloody Moon end reserve timer" is non zero, decrement it. If the new value is zero, the WM_BloodyDay flag is cleared.(这个计时器不是用来倒数血月何时出现的那个,下面详述。)
  • 更新 #山林霸主 flags.

子夜检查

下面这些是子夜检查的内容(就是每次时间从 360.0 变成 0.0 的时候做的事情)。

增加 WM_NumberOfDays(总共过了几个游戏天)。

如果“血月该出现了”

(如果 WM_BloodyDay 是 true)(可以看到東方有紅色滿月就是這個狀態,雙子驛站的西納巴岡會告訴你內心有股騷動。)
  • 如果没办法出现血月(下面有列原因),血月计时器会被设在 2880.0。
  • 如果血月可以出现,播放 Demo011_0(又到了红月出现的时刻,林克你要小心), 然后血月计时器归零。

“好久没有血月了”

  • 如果 FirstTouchdown flag is set(出台地了)而且血月计时器 > 2520.0 (游戏内过了整整七天,营火快转不算):
    • WM_BloodyDay 设为 true,代表下个子夜检查时就会执行上面的“血月该出现了”。
    • 血月计时器归零。
  • Otherwise, the "Bloody end reserve timer" is set to 150. This ensures that the WM_BloodyDay flag is cleared 5 in-game minutes (= 5 seconds in real life) after a Blood Moon occurs.

阻止血月的理由

下面任何一件事情都会阻止血月。

  • 不在MainField (main overworld) (在神庙里之类的地方)
  • IsInHyruleCastleArea is set(在城堡里之类的地方)
  • LastBossGanonBeastGenerateFlag is set(在打魔兽加侬)
  • BloodyMoonProhibition is set
  • Wind_Relic_BattleStart is set (在打瓦‧梅德)
  • Electric_Relic_Battle is set (在打瓦‧娜波力斯)
  • Water_Relic_BattleTime is set (在打瓦‧露塔)
  • SkyMgr's field_2B4 is set to 15 and field_2B8 >= 1.0

请注意:即使血月被阻止,血月计时器也不会归零,还是会继续增加。这些理由也不能阻止 WM_BloodyDay 被设成 true。

注意二:瓦‧鲁达尼亚看似没有在这个表里,但是瓦‧鲁达尼亚会去设 BloodyMoonProhibition,所以血月还是不会出现。

日夜标签

这些标签让程式的其他部分可以用有语义的方式检查现在是早上还是晚上等等。

From 00:00 to 06:00 (closed interval) and from 18:00 to 00:00 (closed interval), WM_DaytimeFlag is set to false and WM_NighttimeFlag is true.

In any other case, WM_DaytimeFlag is set to true and WM_NighttimeFlag to false.

In any other case, WM_DaytimeFlag is set to true and WM_NighttimeFlag to false.

Time division, IsMorning, IsNoon, etc.

Start End Division Time type (1) Time type (2)
04:00 05:00 0 MorningA Morning_A1
05:00 07:00 0 MorningA Morning_A2
07:00 10:00 1 MorningB Morning_B
10:00 13:00 2 NoonA Noon_A
13:00 17:00 3 NoonB Noon_B
17:00 19:00 4 EveningA Evening_A
19:00 21:00 5 EveningB Evening_B
21:00 00:00 6 NightA Night_A
00:00 04:00 7 NightB Night_B

Note: all intervals include the start time and exclude the end time.

月相

月相取决于你在游戏里活了几天 (WM_NumberOfDays)。精确的式子是 (numberOfDays + x + 1) % 8[1],这里的 x 在下午的时候是 1,上午的时候是 0。 百分号是模运算(除以八的余数)。 也就是说,每过一次正午月相就前进一格。 从 0 开始,满月、十六夜、下弦月、残月、新月、眉月、上弦月、十三夜。

如果有什么东西直接设定月相的话 (例如 AIDef:Action/EventSetMoonType),那月相就会是设定过的值。

这个函数 AIDef:Query/WhatMoonName 会回传月相。 双子驿站的西纳巴冈在内心没有骚动的时候会告诉你今晚的月相。 请注意:月相跟血月没有任何关系。 血月不只会在本来应该是满月的晚上出现,血月后也不会接到下弦月。

山林霸主

山林霸主会在 AnimalMaster_Appearance flag 是 true 的时候出现。 山林霸主出不出现是由一个有限状态自动机控制的。

Note that whenever a stage is unloaded, the AnimalMaster_Appearance flag is reset to false.

State 0 沉默状态

如果以下全真

  • #月相 是 5(眉月)
  • The AnimalMaster_Existence flag 是 false(山林霸主还没出现)
  • The current map area number is not 64 ("HyruleHill",就是林克处在萨托利山这个区域)

那么游戏会从 [0 .. 22] 这个区间生成一个随机的数值(这个数值代表山林霸主几点出现), 然后进到 State 1。

State 1 蓄势待发状态

如果你进到 map area 64 (萨托利山这个区域)那就回到 State 0(随机数值也作废)。

如果你不在 map area 64,那游戏会一直等等到现在的时间(小时)是上面生成的出现的小时。 (请注意这个检查是每帧都做。) 这时 AnimalMaster_Appearance 设成 true,山林霸主会出现/萨托利山会发光。 然后进到 State 2。

State 2 发光状态

一个游戏内小时后,游戏会纪录星期几,然后进到 State 3.

State 3 准备消失状态

“两天之后” or “‘过了一天’且‘现在的小时 >= 出现的小时’”,山林霸主消失。 (意思是山林霸主只会维持整整 24 游戏内小时/现时分钟。)

State 4 熄灭状态

等月相是 5 的时候再进到 State 0.

WeatherMgr

Weather types

Name
0 Bluesky
1 Cloudy
2 Rain
3 HeavyRain
4 Snow
5 HeavySnow
6 ThunderStorm
7 ThunderRain
8 BlueskyRain
  1. 0x71010E8200