This is very experimental, since the process of states is different than bf3/4. The stage is finished, but with some limitations:
- engine doesn't support writing data into the state, which means we have to find all reads alone
- some of limitations happen due to how engine works, and sometimes because there is lack of shaders on maps. Like cloud ones, they use FLOW system or whatever that is.
- visbility changing per state works, and thats only virtual that can write to state
- dirty states are in the map of states, not a single global flag inside visual env manager
- manager of visual env doesnt have any virtuals that would update all of the states with state data argument
- some updaters need to be hooked, because they force their values nevertheless
- amount of std::function with templates and all these nested callbacks make it insanely hard to reverse
- some components aren't possible to edit, or ended up on dead ends to do any runtime changes
UI "framework" is using game's debugrenderer with manual handlers. AI wrote most of logic code, since I was lazy to write it all myself.
This project is for educational and own engine analysis. Proves the point that dynamic weather was all fake promise, and it's same as more than 10 years ago. Still spawning a state that "copies" globalbase of visual environment and lerps visbility to make it "natural". Instead of doing all these callbacks maybe time to finally write proper world manager?
Here is where all reversing begins:
if ( envEnabled )
{
v2 = (*((__int64 (__fastcall **)(__int64 (__fastcall ***)()))*off_1497CB1E0[0] + 35))(off_1497CB1E0[0]);
v236 = 193466372;
v3 = v2;
v234 = sub_145C16F30;
v242 = sub_145C16F30;
v232[0] = sub_145D915F0;
v235 = "Sky";
v240[0] = sub_145D915F0;
v238 = sub_145BD0630;
v233 = sub_14051D060;
v239 = sub_145BD06A0;
v237 = 1;
v241 = sub_14051D060;
v243 = 193466372;
sub_14152B930((__int64)v244, (__int64)&v235);
sub_14152D000(v3 + 3744, (__int64)&v249, v4, &v243);
if ( v248 )
v248(v246, 0, 0);
if ( v241 && v241 != sub_14051D060 )
v241(v240, 0, 0);
v5 = VeSky__get(v3 + 9568);
(*(void (__fastcall **)(__int64))(*(_QWORD *)v5 + 48LL))(v5);
if ( v233 && v233 != sub_14051D060 )
v233(v232, 0, 0);
LOBYTE(v221) = v269;
v6 = sub_140C7FB40(qword_149E4BE18, 0x500u, 16, (unsigned int)dword_14A1F1C18, v221);
v7 = (_QWORD *)v6;
if ( v6 )
{
sub_145BEB1A0(v6, "VeSky", "VisualEnvironment");
*v7 = off_148F7E698;
}
else
{
v7 = 0;
}
v251[1] = sub_1405F3F30;
v251[0] = v7;
(*((void (__fastcall **)(__int64 (__fastcall ***)(), __int64, __int64, _QWORD *))*off_1497CB1E0[0] + 33))(
off_1497CB1E0[0],
193466372,
225522839,
v251);
}not all components have updater callback, sky is easiest example to look at. For effects, EffectSystem xref was a key to find all, and xrefing until I got bored eventually.
- spawn any effect
- edit per-state VE
- edit global VE
- camera edits
- edit basic postfx settings
Anticheat is your worry, make hooks pass without allocations detections = 99% done
- ErectBAN (camera idea)