private bool Begin() { IntPtr cellPtr; Memory.InvokeCdecl(GidFileGenerationTask.addr_EnterLock); try { cellPtr = Memory.InvokeCdecl(GidFileGenerationTask.addr_WSLoadCellByCoordinates, this.Parent.WorldSpace.Cast <NetScriptFramework.SkyrimSE.TESWorldSpace>(), this.X, this.Y); } catch { GidFileGenerationTask.KillProcess(); return(false); } finally { Memory.InvokeCdecl(GidFileGenerationTask.addr_ExitLock); } if (cellPtr == IntPtr.Zero) { return(false); } this.Cell = MemoryObject.FromAddress <NetScriptFramework.SkyrimSE.TESObjectCELL>(cellPtr); if (this.Cell == null) { throw new NullReferenceException("this.Cell"); } return(true); }
private bool Process() { if (this.Cell == null) { return(false); } double pct = 0.0; if (this.Parent.TotalCellDo > 0) { pct = Math.Max(0.0, Math.Min((double)this.Parent.DidCellDo / (double)this.Parent.TotalCellDo, 1.0)) * 100.0; } string msg = "Generating grass for " + this.Parent.Name + "(" + this.X + ", " + this.Y + ") " + pct.ToString("0.##") + " pct, world " + (GidFileGenerationTask.DoneWS + 1) + " out of " + GidFileGenerationTask.TotalWS; GidFileGenerationTask.write_all_message(msg); using (var alloc = Memory.Allocate(0x20)) { Memory.WriteZero(alloc.Address, 0x20); Memory.WriteFloat(alloc.Address, this.Cell.CoordinateX * 4096.0f + 2048.0f); Memory.WriteFloat(alloc.Address + 4, this.Cell.CoordinateY * 4096.0f + 2048.0f); Memory.WriteFloat(alloc.Address + 8, 0.0f); try { Memory.InvokeCdecl(GidFileGenerationTask.addr_SetPlrTo, NetScriptFramework.SkyrimSE.PlayerCharacter.Instance.Cast <NetScriptFramework.SkyrimSE.PlayerCharacter>(), alloc.Address, alloc.Address + 0x10, this.Cell.Cast <NetScriptFramework.SkyrimSE.TESObjectCELL>(), 0); } catch { GidFileGenerationTask.KillProcess(); return(false); } } return(true); }
internal static void run_freeze_check() { while (true) { if (cur_state != 1) { break; } int last = System.Threading.Interlocked.CompareExchange(ref _lastDidSomething, 0, 0); int now = Environment.TickCount; if (unchecked (now - last) < 60000) { System.Threading.Thread.Sleep(1000); continue; } //NetScriptFramework.Main.CriticalException("Grass generation appears to have frozen! Restart the game.", false); GidFileGenerationTask.KillProcess(); return; } }
internal static void apply() { var addr = Main.GameInfo.GetAddressOf(13148, 0x2B25 - 0x2220, 0, "E8"); Memory.WriteNop(addr, 5); addr = Main.GameInfo.GetAddressOf(13190, 0xD40 - 0xC70, 0, "E8"); Memory.WriteHook(new HookParameters() { Address = addr, IncludeLength = 5, ReplaceLength = 5, Before = ctx => { System.Threading.Interlocked.Increment(ref queued_grass_counter); } }); addr = Main.GameInfo.GetAddressOf(13190, 0xD71 - 0xC70, 0, "48 8B 74 24 48"); Memory.WriteHook(new HookParameters() { Address = addr, IncludeLength = 5, ReplaceLength = 5, Before = ctx => { System.Threading.Interlocked.Exchange(ref queued_grass_mode, 0); } }); addr = Main.GameInfo.GetAddressOf(15202, 0xA0E - 0x890, 0, "8B 05"); Memory.WriteHook(new HookParameters() { Address = addr, IncludeLength = 0, ReplaceLength = 6, Before = ctx => { ctx.AX = new IntPtr(ChosenGrassGridRadius); } }); addr = Main.GameInfo.GetAddressOf(13138, 0, 0, "48 8B 51 38"); Memory.WriteHook(new HookParameters() { Address = addr, IncludeLength = 0, ReplaceLength = 8, Before = ctx => { var cellPtr = Memory.ReadPointer(ctx.CX + 0x38); Memory.InvokeCdecl(addr_AddGrassNow, Memory.ReadPointer(addr_GrassMgr), cellPtr, ctx.CX + 0x48); var cell = MemoryObject.FromAddress <NetScriptFramework.SkyrimSE.TESObjectCELL>(cellPtr); if (cell != null) { var ws = cell.WorldSpace; if (ws != null) { string wsn = ws.EditorId; int x = cell.CoordinateX; int y = cell.CoordinateY; cur_instance.WriteProgressFile(GidFileGenerationTask.KeyCell, wsn, x, y); } } System.Threading.Interlocked.Decrement(ref queued_grass_counter); } }); Memory.WriteUInt8(addr + 8, 0xC3, true); NetScriptFramework.SkyrimSE.Events.OnFrame.Register(e => { if (cur_state == 1) { if (System.Threading.Interlocked.CompareExchange(ref queued_grass_counter, 0, 0) != 0) { return; } if (System.Threading.Interlocked.Exchange(ref queued_grass_mode, 1) != 0) { return; } System.Threading.Interlocked.Exchange(ref _lastDidSomething, Environment.TickCount); if (!cur_instance.RunOne()) { if (GidFileGenerationTask.Crashed) { GidFileGenerationTask.KillProcess(); NetScriptFramework.SkyrimSE.Main.Instance.QuitGame = true; return; } cur_state = 2; write_all_message("Grass generation finished successfully!"); NetScriptFramework.Main.CriticalException("Grass generation finished successfully!", false); NetScriptFramework.SkyrimSE.Main.Instance.QuitGame = true; } } }, 200, 0); // Allow game to be alt-tabbed and make sure it's processing in the background correctly. addr = Main.GameInfo.GetAddressOf(35565, 0x216 - 0x1E0, 0, "74 14"); Memory.WriteUInt8(addr, 0xEB, true); NetScriptFramework.SkyrimSE.Events.OnMainMenu.Register(e => { Memory.WriteUInt8(Main.GameInfo.GetAddressOf(508798) + 8, 1); // Skyrim.ini [General] bAlwaysActive=1 Memory.WriteUInt8(Main.GameInfo.GetAddressOf(501125) + 8, 0); // Skyrim.ini [Grass] bAllowLoadGrass=0 }); }