1#pragma once
2
3#include <container/seadBuffer.h>
4#include <container/seadPtrArray.h>
5#include <container/seadSafeArray.h>
6#include <hostio/seadHostIONode.h>
7#include <mc/seadJobQueue.h>
8#include <prim/seadSizedEnum.h>
9#include <utility/aglAtomicPtrArray.h>
10#include <utility/aglParameter.h>
11#include <utility/aglParameterIO.h>
12#include <utility/aglParameterObj.h>
13#include "KingSystem/Resource/resHandle.h"
14#include "KingSystem/System/StageInfo.h"
15#include "KingSystem/Utils/Types.h"
16#include "KingSystem/World/worldChemicalMgr.h"
17#include "KingSystem/World/worldDefines.h"
18#include "KingSystem/World/worldDofMgr.h"
19#include "KingSystem/World/worldEnvMgr.h"
20#include "KingSystem/World/worldShootingStarMgrEx.h"
21#include "KingSystem/World/worldSkyMgr.h"
22#include "KingSystem/World/worldTempMgr.h"
23#include "KingSystem/World/worldTimeMgr.h"
24#include "KingSystem/World/worldWeatherMgr.h"
25#include "KingSystem/World/worldWindMgr.h"
26
27namespace sead {
28class WorkerMgr;
29}
30
31namespace ksys::world {
32
33struct ClimateInfo {
34 static constexpr int NumClimateTemp = 11;
35
36 agl::utl::Parameter<int> WeatherType;
37 agl::utl::Parameter<int> WeatherBlueskyRate;
38 agl::utl::Parameter<int> WeatherCloudyRate;
39 agl::utl::Parameter<int> WeatherRainRate;
40 agl::utl::Parameter<int> WeatherHeavyRainRate;
41 agl::utl::Parameter<int> WeatherStormRate;
42 agl::utl::Parameter<bool> DayLockBlueSky;
43 agl::utl::Parameter<bool> NightLockBlueSky;
44 sead::SafeArray<agl::utl::Parameter<float>, NumClimateTemp> ClimateTempDay;
45 sead::SafeArray<agl::utl::Parameter<float>, NumClimateTemp> ClimateTempNight;
46 agl::utl::Parameter<float> MoistureMax;
47 agl::utl::Parameter<float> MoistureMin;
48 agl::utl::Parameter<float> WindPower;
49 agl::utl::ParameterObj obj;
50 u32 WindDirectionType;
51 float WindPowerMultiplier;
52 agl::utl::Parameter<int> IgnitedLevel;
53 agl::utl::Parameter<sead::Color4f> FeatureColor;
54 agl::utl::Parameter<float> CalcRayleigh;
55 agl::utl::Parameter<float> CalcMieSymmetrical;
56 agl::utl::Parameter<float> CalcMie;
57 agl::utl::Parameter<float> CalcSfParamNear;
58 agl::utl::Parameter<float> CalcSfParamAttenuation;
59 agl::utl::Parameter<float> CalcAmbientIntencity;
60 agl::utl::Parameter<float> CalcVolumeMaskIntencity;
61 agl::utl::Parameter<int> PaletteSetSelect;
62 agl::utl::Parameter<int> FogType;
63 agl::utl::Parameter<bool> ForbidComeback;
64 agl::utl::Parameter<int> BlueSkyRainPat;
65};
66KSYS_CHECK_SIZE_NX150(ClimateInfo, 0x600);
67
68class WorldInfo : public agl::utl::IParameterIO, public sead::hostio::Node {
69public:
70 WorldInfo() : agl::utl::IParameterIO("winfo", 0) {}
71
72 u8 _1d8[0x20];
73 res::Handle mResHandle;
74 sead::Buffer<ClimateInfo> mClimates;
75};
76KSYS_CHECK_SIZE_NX150(WorldInfo, 0x258);
77
78class DungeonEnv : public agl::utl::IParameterIO, public sead::hostio::Node {
79public:
80 DungeonEnv() : agl::utl::IParameterIO("dgnenv", 0) {}
81
82 u8 _1d8[0x20];
83 res::Handle mResHandle;
84 agl::utl::Parameter<float> mLightLongitude;
85 agl::utl::Parameter<sead::FixedSafeString<32>> mDungeonSize;
86 agl::utl::Parameter<sead::FixedSafeString<32>> mDungeonType;
87 agl::utl::ParameterObj mDungeonEnvObj;
88};
89KSYS_CHECK_SIZE_NX150(DungeonEnv, 0x338);
90
91// FIXME: incomplete
92class Manager : public sead::hostio::Node {
93 SEAD_SINGLETON_DISPOSER(Manager)
94 Manager();
95 virtual ~Manager();
96
97public:
98 WeatherType getWeatherType() const;
99 void setWeatherType(u32 weather_type, bool x, bool y, bool for_demo);
100 void setWeatherType(const sead::SafeString& weather_type, bool x, bool y, bool for_demo);
101 static const char* getWeatherTypeString(u32 type);
102 static const char* getWeatherTypeString(WeatherType type) {
103 return getWeatherTypeString(u32(type));
104 }
105
106 Climate getClimate(const sead::Vector3f& pos) const;
107 Climate getCurrentClimate() const;
108 Climate getPrevClimate() const;
109 float getClimateTransitionProgress() const;
110
111 bool isDayLockBlueSky(Climate climate) const;
112 bool isNightLockBlueSky(Climate climate) const;
113
114 bool isRaining(const sead::Vector3f& pos) const;
115
116 float calcTempDay(float height) const;
117 float calcTempNight(float height) const;
118
119 float getMoistureMax() const;
120 float getMoistureMin() const;
121
122 sead::Vector3f getWindDirection() const;
123 float getWindSpeed() const;
124 float getWindSpeed(const sead::Vector3f& pos) const;
125 sead::Vector3f getWindDirection(const sead::Vector3f& pos) const;
126
127 int getIgnitedLevel(const sead::Vector3f& pos) const;
128
129 int getPaletteSetSelect() const;
130 int getFogType() const;
131 bool isForbidComeback() const;
132 bool isForbidComeback(Climate climate) const;
133
134 void unload();
135 void init(sead::Heap* heap);
136 void resetForStageUnload();
137 void loadWorldInfoRes();
138 void onStageInit(StageType stage_type, bool is_demo, bool is_main_field);
139 void updateRemainsType();
140 void updateGraphicsMap(StageType type);
141
142 void initBeforeStageGen();
143 void unload2();
144 void clearArray();
145
146 int getWeatherBlueskyRate(Climate climate) const;
147 int getWeatherCloudyRate(Climate climate) const;
148 int getWeatherRainRate(Climate climate) const;
149 int getWeatherHeavyRainRate(Climate climate) const;
150 int getWeatherStormRate(Climate climate) const;
151
152 void calc1(sead::WorkerMgr* mgr);
153 void calc2(sead::WorkerMgr* mgr);
154 void calc3(sead::WorkerMgr* mgr);
155
156 // TODO: more Chemical functions
157 void updateChemicalFarObj();
158
159 void calcEntryJob();
160
161 void changeWind(int direction, bool enable_auto_wind, float speed);
162 void setManualWind(bool enable_auto_wind, sead::Vector3f dir, float speed);
163 void resetManualWind();
164
165 void setDirectionalLight(float angle_x, float angle_y);
166 void setDirectionalLightYang(float value);
167
168 bool isGerudoDesertClimate() const;
169
170 bool hasCameraOrPlayerMoved(float distance_threshold) const;
171
172 int getDungeonSize() const;
173 int getDungeonType() const;
174 float getDungeonLightLongitude() const;
175
176 void setCameraDistForRemainsElectric(sead::Vector3f pos);
177 void setFocusDist(float dist);
178
179 void rerollClimateWindPowers();
180 void forceResetManualWind();
181 void setTemperatureDay(float temp);
182 void setTemperatureNight(float temp);
183 void setIgnitedLevel(int level, float radius, sead::Vector3f center);
184
185 void onEventFlowEnd();
186
187 // TODO: more functions
188
189 bool isMainField() const { return mIsMainField && mStageType == StageType::OpenWorld; }
190
191 bool isAocField() const {
192 return mStageType == StageType::OpenWorld && mFieldType == FieldType::AocField &&
193 mScalingMode == ScalingMode::Disabled;
194 }
195
196 bool isDemo() const { return mIsDemo; }
197 StageType getStageType() const { return mStageType; }
198 FieldType getFieldType() const { return mFieldType; }
199 ScalingMode getScalingMode() const { return mScalingMode; }
200 CalcType getCalcType() const { return mCalcType; }
201
202 TimeMgr* getTimeMgr() const { return static_cast<TimeMgr*>(mMgrs[0]); }
203 SkyMgr* getSkyMgr() const { return static_cast<SkyMgr*>(mMgrs[1]); }
204 ShootingStarMgr* getShootingStarMgr() const { return static_cast<ShootingStarMgr*>(mMgrs[2]); }
205 WeatherMgr* getWeatherMgr() const { return static_cast<WeatherMgr*>(mMgrs[3]); }
206 TempMgr* getTempMgr() const { return static_cast<TempMgr*>(mMgrs[4]); }
207 WindMgr* getWindMgr() const { return static_cast<WindMgr*>(mMgrs[5]); }
208 EnvMgr* getEnvMgr() const { return static_cast<EnvMgr*>(mMgrs[6]); }
209 DofMgr* getDofMgr() const { return static_cast<DofMgr*>(mMgrs[7]); }
210 ChemicalMgr* getChemicalMgr() const { return static_cast<ChemicalMgr*>(mMgrs[8]); }
211
212 bool worldInfoLoaded() const { return mWorldInfoLoadStatus != WorldInfoLoadStatus::NotLoaded; }
213
214 u8 sub_71010F337C(const sead::Vector3f& pos); // TODO implement this : 0x71010F337C - maybe has
215 // a different parameter type
216
217private:
218 enum class WorldInfoLoadStatus : u8 {
219 NotLoaded,
220 Loaded,
221 Unloaded,
222 };
223
224 void overrideWindSpeed(float* wind_speed) const;
225
226 void calcManagers(sead::WorkerMgr* worker_mgr);
227 void updateOverrides();
228 void updateTimers();
229 void updateWindDirections();
230 void updateFieldType();
231
232 static constexpr float PlaceholderTemp = 99999.9;
233
234 WorldInfo mWorldInfo;
235 DungeonEnv mDungeonEnv;
236 sead::DirectResource* mInfoRes{};
237
238 sead::PtrArray<Job> mMgrs;
239 agl::utl::AtomicPtrArray<void*> mAtomicPtrArray;
240 sead::BitFlag32 _5e0 = 1;
241 CalcType mCalcType = CalcType::Invalid;
242 sead::FixedSizeJQ mJobQueue;
243
244 sead::Vector3f mCameraPos{0, 0, 0};
245 sead::Vector3f mPrevCameraPos{0, 0, 0};
246 sead::Vector3f mPlayerPos{0, 0, 0};
247 sead::Vector3f mPrevPlayerPos{0, 0, 0};
248
249 StageType mStageType{};
250 StageType mStageType2{};
251
252 u32 mTicks = 0;
253 int mTimer = 30;
254 u32 _6c8 = 0;
255 bool _6cc = false;
256 bool mGameSceneInitialized = false;
257
258 sead::SafeArray<float, NumClimates> mWindDirections;
259 u32 _720 = 0;
260 sead::Vector3f mWindDir{0, 0, -1};
261 sead::Vector3f mDirectionalLightVecA{0, 1, 0};
262 sead::Vector3f mDirectionalLightVecB{0, 1, 0};
263 sead::Vector3f mIgnitedCenter{0, 0, 0};
264 float mClimateTransitionProgress = 1.0;
265 float mMapEdgeWindSpeed = 1.0;
266 float mManualWindSpeed = 5.0;
267 float mTempDirectDayExtra = PlaceholderTemp;
268 float mTempDirectNightExtra = PlaceholderTemp;
269 float mTempDirectDay = PlaceholderTemp;
270 float mTempDirectNight = PlaceholderTemp;
271 float _770 = 0.0;
272 float mFocusDist = 100.0;
273 float mIgnitedRadius = -1.0;
274 u32 _77c = 9;
275 Climate mCurrentClimate{};
276 Climate mPrevClimate{};
277 int mWindDirectionType = 0;
278 int mManualWindTimer = 0;
279 u32 mMapEdgeWindDirectionType = 0;
280 int mWeatherTypeTimer = 0;
281 int _798 = -1;
282 int _79c = 0;
283 int mTempDirectTimer = 0;
284 int mTempDirectDayTimer = 0;
285 int mTempDirectNightTimer = 0;
286 u32 _7ac = 0;
287 int mIgnitedTimer = 0;
288 int mIgnitedLevel = 0;
289 u32 _7b8 = 0;
290 RemainsType mRemainsType{};
291 FieldType mFieldType{};
292 ScalingMode mScalingMode{};
293 int mWindChangeFinalTimer = 0;
294 float mWindSpeedAocField = 0.75;
295 WorldInfoLoadStatus mWorldInfoLoadStatus = WorldInfoLoadStatus::NotLoaded;
296 WeatherType mWeatherType = WeatherType::Invalid;
297 u8 mDirectionalLightTimer = 0;
298 bool mEnableAutoWind = true;
299 bool mMapEdgeWindEnabled = false;
300 bool _7d5 = false;
301 bool mWeatherSetForDemo = false;
302 u8 _7d7 = 0;
303 bool mIsDemo = false;
304 bool mIsMainField = false;
305 bool mIsBattleCurseR = false;
306 bool mInFinalTrialBossBattleArea = false;
307};
308KSYS_CHECK_SIZE_NX150(Manager, 0x7e0);
309
310} // namespace ksys::world
311