Thread 1: http://www.gamesas.com/topic/1287595-relwip-skyrim-elys-uncapper/
The original project was named Skyrim -Elys- Uncapper. As of last day, it has more turned into an open development as more peoples may have an interest to develop a similar plugin, most probably using C++ and a code more "attuned" with SKSE , and as the new version would have not be done if not for such involvement.
=====================================
Skyrim -Community- Uncapper v1.13.0.1
=====================================
1. Description
2. Requirements
3. Installing
4. Optional Settings
5. Uninstalling
6. Backup
7. Conflicts/Known Errors
8. Credits
9. Contact and Information
10. Disclaimer
===============
1. DESCRIPTION
===============
REQUIRED: REMEMBER TO INSTALL SKYRIM SCRIPT EXTENDER FIRST.
The default settings of this plugin will unlock the skill level caps of 100 and push them to 300. This allows you character to potentially reach level 252.
You will also get benefits from skills above level 100, up to level 400 including enchantement bonuses.
You may also tweaks the settings of this plugin to set your own caps, to modify the experience earning rate of each skill, the relation between skill leveling and player leveling, and to change the number of perks, health points, magicka points, stamina points, "Carry Weight" points gained at a specific level up.
See the "4. Optional Settings" section below for such modification.
================
2. REQUIREMENTS
================
Skyrim version 1.5.26 is required. However enabling the AutoUpdate feature may allow the Uncapper to work with another Skyrim version.
Skyrim Script Extender ( http://skse.silverlock.org/)
==============
3. INSTALLING
==============
Extract the content of this archive into your Skyrim folder. ( by default the folder is "C:\Program Files (x86)\Steam\SteamApps\common\skyrim" )
If correctly extracted you should find SKSE_Elys_Uncapper.dll and SKSE_Elys_Uncapper.ini inside your "
==========================
4. OPTIONAL SETTINGS
==========================
You have the possibility to set a different skill level cap of your choice for each different skill.
You can modify each different rate at which your character earns each respective skill experience.
You can set the max skill level used by the game formulas when calculating skill benefits.
You can decide how fast leveling a skill does level the player's character.
You can decide how many points you want to earn at each level up for: Health, Magicka, Stamina and "Carry Weight".
To do so you have to modify SKSE_Elys_Uncapper.ini with a basic text editor such as Notepad.
IF YOU DON'T KNOW HOW WORKS AND HOW TO MODIFY AN INI FILE PLEASE READ: http://en.wikipedia.org/wiki/INI_file
Example of SKSE_Elys_Uncapper.ini::
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IF YOU DON'T KNOW HOW WORKS AND HOW TO MODIFY AN INI FILE PLEASE READ:; http://en.wikipedia.org/wiki/INI_file;; Anything behind a semicolon is considered a comment and has no effect;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;[General];DO NOT MODIFY THIS VALUE;INI file versioniINIFileVersion = 3;Enable(1) or Disable(0) the plugin;Default value = http://forums.bethsoft.com/topic/1342084-relskyrim-community-uncapper-previously-elys-thread-2/0bEnabled=1;Enable(1) or Disable(0) the AutoUpdate functionality. IT MIGHT NOT WORK WITH CERTAIN SKYRIM VERSION! ENABLE AT YOUR OWN RISK!;Default value = 0bAutoUpdate=0;Enable(1) or Disable(0) the Uncapper Skill Level Caps;;Default value = 0bUseSkillCaps=1;Enable(1) or Disable(0) the Uncapper Skill caps inside formulas governed by skills.;Default value = 0bUseSkillFormulaCaps=1;Enable(1) or Disable(0) the ingame Enchanter Uncapper skill caps;Default value = 0bUseEnchanterCaps=1;Enable(1) or Disable(0) the Uncapper Skill Experience Gained Multipliers;;Default value = 0bUseSkillExpGainMults=0;Enable(1) or Disable(0) the Uncapper Skill Experience to Player's Character Experience Multipliers;;Default value = http://forums.bethsoft.com/topic/1342084-relskyrim-community-uncapper-previously-elys-thread-2/0bUsePCLevelSkillExpMults=0;Enable(1) or Disable(0) the number of perks gained, set by the Uncapper, at each level up;Default value = 0bUsePerksAtLevelUp=0;Enable(1) or Disable(0) the number of health points, set by the Uncapper, gained at each level up when Health is selected during the Level Up screen;Default value = 0bUseHealthAtLevelUp=0;Enable(1) or Disable(0) the number of magicka points, set by the Uncapper, gained at each level up when Magicka is selected during the Level Up screen;Default value = 0bUseMagickaAtLevelUp=0;Enable(1) or Disable(0) the number of stamina points, set by the Uncapper, gained at each level up when Stamina is selected during the Level Up screen;Default value = 0bUseStaminaAtLevelUp=0;Enable(1) or Disable(0) the number of"Carry Weight" points, set by the Uncapper, gained at each level up when Health is selected during the Level Up screen;Default value = http://forums.bethsoft.com/topic/1342084-relskyrim-community-uncapper-previously-elys-thread-2/0bUseCarryWeightAtHealthLevelUp=0;Enable(1) or Disable(0) the number of"Carry Weight" points, set by the Uncapper, gained at each level up when Magicka is selected during the Level Up screen;Default value = http://forums.bethsoft.com/topic/1342084-relskyrim-community-uncapper-previously-elys-thread-2/0bUseCarryWeightAtMagickaLevelUp=0;Enable(1) or Disable(0) the number of"Carry Weight" points, set by the Uncapper, gained at each level up when Stamina is selected during the Level Up screen;Default value = http://forums.bethsoft.com/topic/1342084-relskyrim-community-uncapper-previously-elys-thread-2/0bUseCarryWeightAtStaminaLevelUp=0[SkillCaps]; Set the Skill Level Cap to; Between 0 and 10000;; Using too low or too high values may crash the game. Handle them with caution.; Default game value = 100iAlchemy=300iAlteration=300iArchery=300iBlock=300iConjuration=300iDestruction=300iEnchanting=300iHeavyArmor=300iIllusion=300iLightArmor=300iLockpicking=300iOneHanded=300iPickpocket=300iRestoration=300iSmithing=300iSneak=300iSpeech=300iTwoHanded=300[SkillFormulaCaps]; Set the Skill Formula Cap to; If your skill level is higher than the cap set below, then the skill level showing in game will be capped and displayed in red color (like if it was affected by a negative enchantment); Between 0 and 10000;; Using too low or too high values may crash the game. Handle them with caution.; Default game value = 100iAlchemy=400iAlteration=400iArchery=400iBlock=400iConjuration=400iDestruction=400iEnchanting=400iHeavyArmor=400iIllusion=400iLightArmor=400iLockpicking=400iOneHanded=400iPickpocket=400iRestoration=400iSmithing=400iSneak=400iSpeech=400iTwoHanded=400[EnchanterCaps];However high the Enchanting skill is, the following values set an Enchanting skill level cap when using the ingame Enchanter.;If bSkillFormulaCaps is enabled, then the following values are also capped by iEnchanting inside [SkillFormulaCaps], if iEnchanting is lower.; Between 0 and 10000;;Max Enchanting skill level for enchantment magnitude.iMaxEnchantingLevelForMagnitude=400;Max Enchanting skill level for enchantment charges;A value higher than 199 will cause inconsistencies in vanilla Skyrim.iMaxEnchantingLevelForCharges=199[SkillExpGainMults]; Set the Skill Experience Gained Multiplier to; betwen 0.0 and 10000.0; Using too low or too high values may crash the game. Handle them with caution.; Default game value = 1.0fAlchemy=1.0fAlteration=1.0fArchery=1.0fBlock=1.0fConjuration=1.0fDestruction=1.0fEnchanting=1.0fHeavyArmor=1.0fIllusion=1.0fLightArmor=1.0fLockpicking=1.0fOneHanded=1.0fPickpocket=1.0fRestoration=1.0fSmithing=1.0fSneak=1.0fSpeech=1.0fTwoHanded=1.0[PCLevelSkillExpMults]; Set the Skill Experience to Player's Character Experience Multipliers to; betwen 0.0 and 10000.0; Using too low or too high values may crash the game. Handle them with caution.; Default game value = http://forums.bethsoft.com/topic/1342084-relskyrim-community-uncapper-previously-elys-thread-2/1.0fAlchemy=1.0fAlteration=1.0fArchery=1.0fBlock=1.0fConjuration=1.0fDestruction=1.0fEnchanting=1.0fHeavyArmor=1.0fIllusion=1.0fLightArmor=1.0fLockpicking=1.0fOneHanded=1.0fPickpocket=1.0fRestoration=1.0fSmithing=1.0fSneak=1.0fSpeech=1.0fTwoHanded=1.0[PerksAtLevelUp];Set the number of perks gained at each level up. If a specific level is not specified then the closest lower level setting is used.;Default game value is one perk per level (you can also use float as value, for example 1.25 per points per level); Level (2..10000) = Perks (0..255);;In the following inactive commented example the player will gain 1 perk per level at and from level 2 to 9, then 2 perks per level at and from level 10 to 29,; then 4 perks per level at and from level 30 to 94, then no perk at all per level for level 95 and above;;2=1;10=2;30=4;95=02=1[HealthAtLevelUp];Set the number of health points gained at each level up when Health is selected during the Level Up screen. If a specific level is not specified then the closest lower level setting is used.;Default game value is 10 points per level; Level (2..10000) = Points (0..10000);;In the following inactive commented example the player will gain 10 points per level at and from level 2 to 9, then 20 points per level at and from level 10 to 29,; then 40 points per level at and from level 30 to 94, then no points at all per level for level 95 and above;;2=10;10=20;30=40;95=02=10[MagickaAtLevelUp];Set the number of magicka points gained at each level up when Magicka is selected during the Level Up screen. If a specific level is not specified then the closest lower level setting is used.;Default game value is 10 points per level; Level (2..10000) = Points (0..10000);;In the following inactive commented example the player will gain 10 points per level at and from level 2 to 9, then 20 points per level at and from level 10 to 29,; then 40 points per level at and from level 30 to 94, then no points at all per level for level 95 and above;;2=10;10=20;30=40;95=02=10[StaminaAtLevelUp];Set the number of stamina points gained at each level up when Stamina is selected during the Level Up screen. If a specific level is not specified then the closest lower level setting is used.;Default game value is 10 points per level; Level (2..10000) = Points (0..10000);;In the following inactive commented example the player will gain 10 points per level at and from level 2 to 9, then 20 points per level at and from level 10 to 29,; then 40 points per level at and from level 30 to 94, then no points at all per level for level 95 and above;;2=10;10=20;30=40;95=02=10[CarryWeightAtHealthLevelUp];Set the number of"Carry Weight" points gained at each level up when Health is selected during the Level Up screen. If a specific level is not specified then the closest lower level setting is used.;Default game value is 0 points per level; Level (2..10000) = Points (0..10000);;In the following inactive commented example the player will gain 10 points per level at and from level 2 to 9, then 20 points per level at and from level 10 to 29,; then 40 points per level at and from level 30 to 94, then no points at all per level for level 95 and above;;2=10;10=20;30=40;95=02=0[CarryWeightAtMagickaLevelUp];Set the number of "Carry Weight" points gained at each level up when Magicka is selected during the Level Up screen. If a specific level is not specified then the closest lower level setting is used.;Default game value is 0 points per level; Level (2..10000) = Points (0..10000);;In the following inactive commented example the player will gain 10 points per level at and from level 2 to 9, then 20 points per level at and from level 10 to 29,; then 40 points per level at and from level 30 to 94, then no points at all per level for level 95 and above;;2=10;10=20;30=40;95=02=0[CarryWeightAtStaminaLevelUp];Set the number of "Carry Weight" points gained at each level up when Stamina is selected during the Level Up screen. If a specific level is not specified then the closest lower level setting is used.;Default game value is 5 points per level; Level (2..10000) = Points (0..10000);;In the following inactive commented example the player will gain 10 points per level at and from level 2 to 9, then 20 points per level at and from level 10 to 29,; then 40 points per level at and from level 30 to 94, then no points at all per level for level 95 and above;;2=10;10=20;30=40;95=02=5
================
================
5. UNINSTALLING
================
Delete SKSE_Elys_Uncapper.dll and SKSE_Elys_Uncapper.ini from your "
( by default "C:\Program Files (x86)\Steam\SteamApps\common\skyrim\DATA\SKSE\Plugins\" )
And then delete this SKSE_Elys_Uncapper_README.txt.
===============
6. BACKUP
===============
As a surviving golden rule, always backup all your savegames before trying a new mod. Better safe than sorry. It applies to this mod as well.
============================
7. CONFLICTS / KNOWN ERRORS
============================
The only conflicting mods I can think about, are mods that have been designed to alterate or expand how the skills and perks level up.
===========
8. CREDITS
===========
Thanks to SKSE team for their nice work on Skyrim Script Extender

Thanks to Bethesda Softworks for letting us modding their game.
Special thanks to ianpatt for providing the necessary informations so I could made a new version of the Uncapper.
===========================
9. CONTACT AND INFORMATION
===========================
Elys on Bethesda Forums ( http://www.gamesas.com )
===========================
10. DISCLAIMER
===========================
This software is provided 'as-is', without any express or implied
warranty. In no event shall the authors be held liable for any damages
arising from the use of this software.
For developers, Uncapper Source Code (Delphi XE2) v1.13.0.1:
library SKSE_Elys_Uncapper;{$R *.res}{$B-}uses Windows, SysUtils, IniFiles, Classes, pelib in 'pelib.pas';type PluginHandle = Longword; SKSEInterface = packed record skseVersion: Longword; runtimeVersion: Longword; editorVersion: Longword; isEditor: Longword; QueryInterface: procedure(id: Longword); cdecl; GetPluginHandle: function: PluginHandle; cdecl; end; PluginInfo = packed record const kInfoVersion: Longword = 1; var infoVersion: Longword; name: PAnsiChar; version: Longword; end; TRelHop = packed record Code: Byte; Target: Longword; Nops: Word; end; TExeMemory = record Address: Longword; Size: Longword; End; PSkill = ^TSkill; TSkill = packed record Level: Single; CurExp: Single; MaxExp: Single; end; TSkillTable = Array [6 .. 23] of Single; TEnergyAtLevelUp = record Level: Word; Points: Longword; end; TEnergyTable = Array of TEnergyAtLevelUp;const ERROR_PLUGIN = 'Error: Plugin not enabled'; SKYRIM_VER = $051A0000; SKSE_VER = $01040080; PLUGIN_VER = $010D0001; INI_VER = 3; MAX_LEVEL = 10000; fMax_Level: Single = MAX_LEVEL; Zero: Longword = 0; AlterationID = 18; ArcheryID = 8; AlchemyID = 16; ConjurationID = 19; BlockID = 9; LightArmorID = 12; DestructionID = 20; HeavyArmorID = 11; LockpickingID = 14; EnchantingID = 23; OneHandedID = 6; PickpocketID = 13; IllusionID = 21; SmithingID = 10; SneakID = 15; RestorationID = 22; TwoHandedID = 7; SpeechID = 17; FixSneakOver100CheckCode: packed Array [0 .. 5] of Byte = ($9E, // sahf $9B, // wait $DF, $E0, // fstsw ax $90, // nop $73 // jae );var GetLevel: function: Integer; stdcall = nil ; //thiscall FuncIncreaseSkillExp: function(SkillID: Longword; Exp: Single; a3, a4: Integer; a5: Byte; a6: Boolean): Integer; stdcall = nil; // Thiscall GetValueActiveLevelHooked: function( SkillID: Longword): Single; stdcall = nil; bEnabled: Boolean = False; bAutoUpdate: Boolean = False; iIniFileVersion: Integer; bUseSkillFormulaCaps: Boolean; bUseSkillCaps: Boolean; bUseSkillExpGainMults: Boolean; bUsePCLevelSkillExpMults: Boolean; bUsePerksAtLevelUp: Boolean; bUseHealthAtLevelUp: Boolean; bUseMagickaAtLevelUp: Boolean; bUseStaminaAtLevelUp: Boolean; bUseCarryWeightAtHealthLevelUp: Boolean; bUseCarryWeightAtMagickaLevelUp: Boolean; bUseCarryWeightAtStaminaLevelUp: Boolean; bUseEnchanterCaps: Boolean; iMaxEnchantingLevelForMagnitude: Longword; iMaxEnchantingLevelForCharges: Longword; SkillCaps: TSkillTable; SkillFormulaCaps: TSkillTable; SkillExpGainMults: TSkillTable; PCLevelSkillExpMults: TSkillTable; PerksTable: Array [2 .. MAX_LEVEL] of Single; HealthAtLevelUp: TEnergyTable; MagickaAtLevelUp: TEnergyTable; StaminaAtLevelUp: TEnergyTable; CarryWeightAtHealthLevelUp: TEnergyTable; CarryWeightAtMagickaLevelUp: TEnergyTable; CarryWeightAtStaminaLevelUp: TEnergyTable; SneakOver100CheckCode: PByte = nil; CurrentSkillCap: Single;function Overwrite(Address: Pointer; Data: Pointer; Size: Longword): Boolean;var OldFlag: Longword;begin Result := False; if VirtualProtect(Address, Size, PAGE_EXECUTE_READWRITE, @OldFlag) then Move(Data^, Address^, Size) else begin MessageBox(0, 'SKSE Community Uncapper could not modify Skyrim in memory. PLEASE CLOSE THE GAME NOW TO AVOID POTENTIAL GAME INCONSISTANCIES OR CORRUPTION', 'Error', MB_ICONERROR); Exit; end; Result := True;end;function SetRelHop(Opcode: Byte; Address: Pointer; Target: Pointer; EndingNops: Longword): Boolean;var Jmp: TRelHop;begin Jmp.Code := Opcode; Jmp.Nops := $9090; Jmp.Target := Longword(Target) - Longword(Address) - 5; Result := Overwrite(Address, @Jmp, 5 + EndingNops);end;function SetRelCall(Address: Pointer; Target: Pointer; EndingNops: Longword = 0): Boolean;begin Result := SetRelHop($E8, Address, Target, EndingNops);end;function SetRelJmp(Address: Pointer; Target: Pointer; EndingNops: Longword = 0): Boolean;begin Result := SetRelHop($E9, Address, Target, EndingNops);end;function GetExeMemory: TExeMemory;var hd: HModule; ntHeader: PIMAGE_NT_HEADERS; SectionBase: Longword; SectionHeader: PIMAGE_SECTION_HEADER; i: Integer;begin try hd := GetModuleHandle(nil); ntHeader := PIMAGE_NT_HEADERS(Longword(hd) + PIMAGE_DOS_HEADER(hd).e_lfanew); SectionBase := Longword(ntHeader) + SizeOf(IMAGE_NT_HEADERS) - SizeOf(IMAGE_OPTIONAL_HEADER) + ntHeader.FileHeader.SizeOfOptionalHeader; for i := 0 to ntHeader.FileHeader.NumberOfSections - 1 do begin SectionHeader := PIMAGE_SECTION_HEADER(SectionBase + i * SizeOf(IMAGE_SECTION_HEADER)); if SectionHeader.name = '.text' then begin Result.Address := ntHeader.OptionalHeader.ImageBase + SectionHeader.VirtualAddress; Result.Size := SectionHeader.PhysicalAddress; break end; end; except Result.Address := 0; end;end;function GetActorLevel(Actor: Pointer): Word;begin asm mov ecx, Actor; end; Result := GetLevel;end;procedure IncreasePerkPoolSub(Player: PByte); stdcall;var pPerkPool: PByte; LevelIndex: Integer; p: Single;begin LevelIndex := GetActorLevel(Player); pPerkPool := Player + $6C9; if (LevelIndex <= MAX_LEVEL) and (LevelIndex > 1) then p := pPerkPool^ + PerksTable[LevelIndex] else p := pPerkPool^ + 1; if p > 255 then p := 255; pPerkPool^ := Trunc(p);end;var PerksAtLevelUp: PByte = nil;procedure IncreasePerkPool;asm pushad push eax // Player call IncreasePerkPoolSub; popadend;var pPlayer: Pointer; Energy: Longword;procedure IncreaseEnergySub(EnergyID: Longword; pDefaultValue: PInteger); stdcall;var Level: Word; i: Integer; Table: TEnergyTable;begin Energy := pDefaultValue^; case EnergyID of 24: if bUseHealthAtLevelUp then Table := HealthAtLevelUp else Exit; 25: if bUseMagickaAtLevelUp then Table := MagickaAtLevelUp else Exit; 26: if bUseStaminaAtLevelUp then Table := StaminaAtLevelUp else Exit; 10024: If bUseCarryWeightAtHealthLevelUp then Table := CarryWeightAtHealthLevelUp else Begin Energy := 0; Exit; End; 10025: If bUseCarryWeightAtMagickaLevelUp then Table := CarryWeightAtMagickaLevelUp else begin Energy := 0; Exit; end; 10026: If bUseCarryWeightAtStaminaLevelUp then Table := CarryWeightAtStaminaLevelUp else Exit; else Exit; end; Level := GetActorLevel(Pointer(pPlayer^)); for i := 0 to High(Table) do if Level < Table[i].Level then break else if Level = Table[i].Level then begin Energy := Table[i].Points; break; end else Energy := Table[i].Points;end;var LevelUp: PByte = nil; piAVDhmsLevelUp: PInteger;procedure IncreaseEnergy;asm pushad mov eax, [edi+12] push piAVDhmsLevelUp push eax call IncreaseEnergySub popad fild Energyend;var pfLevelUpCarryWeightMod: PSingle;procedure IncreaseCarryWeight;asm pushad mov eax, [edi+12] add eax, 10000 push pfLevelUpCarryWeightMod push eax call IncreaseEnergySub popad mov eax, Energyend;function GetSkill(This: Pointer; SkillID: Longword): PSkill;begin Result := PSkill(PLongword(This)^ + 12 * SkillID - 64);end;var CalculateExpForNextLevel: function(SkillLevel, SLParam1, SLParam2: Single): Single; cdecl; GetSkillCoefficients: function(SkillID: Longword; a2, a3, a4, a5: PSingle): Boolean; cdecl;procedure FixSkillExp(This: Pointer; SkillID: Longword);var f1, f2, SLParam1, SLParam2: Single;begin if GetSkillCoefficients(SkillID, @f1, @f2, @SLParam1, @SLParam2) then with GetSkill(This, SkillID)^ do if (CurExp < 0) or (MaxExp < 0) or ((MaxExp = 0) and (Level < SkillCaps[SkillID])) or ((MaxExp > 0) and (Level >= SkillCaps[SkillID])) then begin CurExp := 0; MaxExp := CalculateExpForNextLevel(Level + 1, SLParam1, SLParam2); end;end;var SkillToCharacterExp: function(a1, a2, a3: Single): Single; cdecl; CurrentPCLevelSkillExpMult: Single;function MySkillToCharacterExp(a1, a2, a3: Single): Single; cdecl;begin Result := SkillToCharacterExp(a1, a2, a3) * CurrentPCLevelSkillExpMult;end;var PreFuncIncreaseSkillExp: PByte = nil; UncapSkillFormula: PByte = nil; NotIncPCS: Boolean = True;function MyFuncIncreaseSkillExp(SkillID: Longword; Exp: Single; a3, a4: Integer; a5: Byte; a6: Boolean): Integer; stdcall; // Thiscallvar This: Pointer;begin asm mov This, ecx; end; if (SkillID >= 6) and (SkillID <= 23) then begin if bUseSkillCaps then begin CurrentSkillCap := SkillCaps[SkillID]; // Fixing corrupted or not updated Skill Experience FixSkillExp(This, SkillID); end; if bUseSkillExpGainMults and NotIncPCS then Exp := Exp * SkillExpGainMults[SkillID]; if bUsePCLevelSkillExpMults then CurrentPCLevelSkillExpMult := PCLevelSkillExpMults[SkillID]; end; asm mov ecx, This; end; Result := FuncIncreaseSkillExp(SkillID, Exp, a3, a4, a5, a6);end;var IncreaseLevelBy: PByte = nil;procedure MyIncreaseSkillLevelBy(SkillID: Longword; Count: Longword); stdcall; // Thiscallvar oActor: PByte; This: Pointer; c: Longword; ExpNeeded: Single; SkillProgression: Double;begin asm mov oActor, ecx end; if Count = 0 then Count := 1; This := Pointer(Pointer(oActor + $618)^); if (SkillID >= 6) and (SkillID <= 23) then begin if bUseSkillCaps then begin CurrentSkillCap := SkillCaps[SkillID]; // Fixing corrupted or not updated Skill Experience FixSkillExp(This, SkillID); end; with GetSkill(This, SkillID)^ do begin if MaxExp = 0 then SkillProgression := 0 else SkillProgression := CurExp / MaxExp; c := 0; repeat ExpNeeded := MaxExp - CurExp; NotIncPCS := False; asm push ecx mov ecx, This end ; MyFuncIncreaseSkillExp(SkillID, ExpNeeded, 0, 0, 0, c < Count - 1); asm pop ecx end ; NotIncPCS := True; Inc(c); until c >= Count; CurExp := CurExp + MaxExp * SkillProgression; end; end; asm mov ecx, oActor end;end;procedure SkillCapPatch;asm fld CurrentSkillCapend;var GetValueActiveLevel: PByte = nil; SkillTableAddr: Longword;function MyGetValueActiveLevel(SkillID: Longword): Single; stdcall; // userpurgebegin asm mov eax, [SkillTableAddr] mov eax, [eax] end; Result := GetValueActiveLevelHooked(SkillID); asm push eax end; if (SkillID >= 6) and (SkillID <= 23) and (Result >= SkillFormulaCaps[SkillID]) then Result := SkillFormulaCaps[SkillID]; asm pop eax end;end;function GetEnchantingLevelFix(MaxLevel: Longword): Single; stdcall; // thiscallbegin Result := MyGetValueActiveLevel(EnchantingID); if Result > MaxLevel then Result := MaxLevel;end;var EnchantingMagnitude: PByte = nil;procedure EnchantingMagnitudeFix;asm push ebx push eax mov eax, [esp+8] mov [esp+8], ebx mov [esp+4], eax pop eax pushad push iMaxEnchantingLevelForMagnitude call GetEnchantingLevelFix popadend;var EnchantingCharge: PByte = nil;procedure EnchantingChargeFix;asm add ecx, 60h pushad push iMaxEnchantingLevelForCharges call GetEnchantingLevelFix popadend;const FuncIncreaseSkillExpSize = 719; FuncIncreaseSkillExpSig: packed array[0..718] of Byte = ( $81,$EC,$F8,$00,$00,$00,$55,$57,$8B,$BC,$24,$04,$01,$00,$00,$8D,$47,$FA,$8B,$E9,$89,$6C,$24,$24,$83,$F8,$11,$0F,$87,$00,$00,$00, $00,$8B,$0D,$00,$00,$00,$00,$8B,$51,$60,$8B,$42,$0C,$83,$C1,$60,$57,$FF,$D0,$D9,$5C,$24,$08,$D9,$44,$24,$08,$D9,$05,$00,$00,$00, $00,$DE,$D9,$DF,$E0,$F6,$C4,$41,$0F,$85,$00,$00,$00,$00,$53,$B8,$00,$00,$80,$3F,$8D,$4C,$24,$20,$51,$8D,$54,$24,$20,$52,$89,$44, $24,$2C,$89,$44,$24,$24,$8D,$44,$24,$20,$50,$8D,$4C,$24,$30,$51,$33,$DB,$57,$89,$5C,$24,$2C,$89,$5C,$24,$34,$E8,$00,$00,$00,$00, $83,$C4,$14,$84,$C0,$0F,$84,$00,$00,$00,$00,$8B,$45,$00,$8D,$14,$7F,$56,$8D,$74,$90,$C0,$38,$9C,$24,$1C,$01,$00,$00,$74,$15,$D9, $44,$24,$28,$D8,$8C,$24,$10,$01,$00,$00,$D8,$44,$24,$1C,$D9,$5C,$24,$14,$EB,$0B,$8B,$8C,$24,$10,$01,$00,$00,$89,$4C,$24,$14,$8B, $15,$00,$00,$00,$00,$8B,$8C,$24,$14,$01,$00,$00,$89,$BA,$B0,$06,$00,$00,$A1,$00,$00,$00,$00,$89,$88,$34,$06,$00,$00,$8B,$15,$00, $00,$00,$00,$8B,$84,$24,$18,$01,$00,$00,$8D,$4C,$24,$14,$89,$82,$B4,$06,$00,$00,$8B,$15,$00,$00,$00,$00,$51,$52,$6A,$16,$E8,$00, $00,$00,$00,$A1,$00,$00,$00,$00,$C7,$80,$B0,$06,$00,$00,$FF,$FF,$FF,$FF,$8B,$0D,$00,$00,$00,$00,$89,$99,$34,$06,$00,$00,$8B,$15, $00,$00,$00,$00,$89,$9A,$B4,$06,$00,$00,$D9,$46,$04,$D8,$44,$24,$20,$83,$C4,$0C,$32,$DB,$D9,$5E,$04,$D9,$44,$24,$10,$D9,$05,$00, $00,$00,$00,$DE,$D9,$DF,$E0,$F6,$C4,$41,$0F,$85,$00,$00,$00,$00,$EB,$04,$8B,$6C,$24,$2C,$8B,$46,$04,$8B,$4E,$08,$89,$44,$24,$38, $D9,$44,$24,$38,$89,$4C,$24,$34,$D9,$44,$24,$34,$DE,$D9,$DF,$E0,$F6,$C4,$41,$0F,$8A,$00,$00,$00,$00,$D9,$46,$04,$8B,$D1,$89,$54, $24,$3C,$D8,$64,$24,$3C,$D9,$5E,$04,$8B,$0D,$00,$00,$00,$00,$8B,$41,$60,$8B,$50,$14,$83,$C1,$60,$51,$C7,$04,$24,$00,$00,$80,$3F, $57,$FF,$D2,$57,$8D,$4C,$24,$34,$B3,$01,$E8,$00,$00,$00,$00,$84,$1D,$00,$00,$00,$00,$75,$1E,$83,$0D,$00,$00,$00,$00,$01,$B9,$00, $00,$00,$00,$E8,$00,$00,$00,$00,$68,$00,$00,$00,$00,$E8,$00,$00,$00,$00,$83,$C4,$04,$8B,$0D,$00,$00,$00,$00,$8D,$44,$24,$30,$50, $51,$B9,$00,$00,$00,$00,$E8,$00,$00,$00,$00,$D9,$44,$24,$10,$D9,$E8,$8B,$54,$24,$24,$8B,$44,$24,$20,$DE,$C1,$83,$EC,$0C,$89,$54, $24,$08,$89,$44,$24,$04,$D9,$5C,$24,$24,$D9,$44,$24,$24,$D9,$1C,$24,$E8,$00,$00,$00,$00,$8B,$4C,$24,$1C,$D9,$5E,$08,$8B,$6D,$00, $83,$C4,$08,$89,$0C,$24,$E8,$00,$00,$00,$00,$D9,$5C,$24,$1C,$D9,$44,$24,$1C,$57,$D8,$45,$00,$D9,$5D,$00,$8B,$15,$00,$00,$00,$00, $52,$E8,$00,$00,$00,$00,$D9,$44,$24,$1C,$D9,$E8,$83,$C4,$0C,$DE,$C1,$D9,$5C,$24,$10,$D9,$44,$24,$10,$D9,$05,$00,$00,$00,$00,$DE, $D9,$DF,$E0,$F6,$C4,$41,$0F,$84,$00,$00,$00,$00,$EB,$04,$84,$DB,$74,$50,$80,$BC,$24,$20,$01,$00,$00,$00,$75,$46,$8B,$0D,$00,$00, $00,$00,$8B,$41,$60,$8B,$50,$0C,$8B,$35,$00,$00,$00,$00,$83,$C1,$60,$57,$FF,$D2,$E8,$00,$00,$00,$00,$50,$57,$E8,$00,$00,$00,$00, $83,$C4,$04,$50,$8D,$44,$24,$48,$56,$50,$E8,$00,$00,$00,$00,$6A,$00,$6A,$00,$8D,$4C,$24,$58,$51,$6A,$14,$E8,$00,$00,$00,$00,$83, $C4,$20,$5E,$5B,$5F,$5D,$81,$C4,$F8,$00,$00,$00,$C2,$18,$00); FuncIncreaseSkillExpMask: packed array[0..718] of Byte = ( $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00, $00,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00, $00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00, $00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$00, $00,$00,$00,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00, $00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$00, $00,$00,$00,$FF,$00,$00,$00,$00,$FF,$00,$00,$00,$00,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$00,$00,$00,$00,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00, $FF,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00, $00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$00,$00,$00,$00, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF); UncapSkillFormulaSize = 90; UncapSkillFormulaSig: packed array [0 .. 89] of Byte = ($51, $8B, $15, $00, $00, $00, $00, $8B, $44, $24, $08, $8B, $44, $82, $04, $8B, $40, $38, $8B, $4C, $24, $0C, $8B, $D0, $C1, $EA, $04, $89, $0C, $24, $F6, $C2, $01, $74, $37, $D9, $44, $24, $0C, $D9, $05, $00, $00, $00, $00, $DE, $D9, $DF, $E0, $F6, $C4, $41, $74, $05, $B9, $00, $00, $C8, $42, $D9, $EE, $89, $4C, $24, $0C, $D9, $44, $24, $0C, $DE, $D9, $DF, $E0, $F6, $C4, $05, $7A, $02, $33, $C9, $89, $0C, $24, $D9, $04, $24, $59, $C2, $08, $00); UncapSkillFormulaMask: packed array [0 .. 89] of Byte = ($FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF); SneakOver100CheckCodeSize = 82; SneakOver100CheckCodeSig: packed array [0 .. 81] of Byte = ($50, $57, $55, $6A, $01, $8B, $CB, $E8, $00, $00, $00, $00, $84, $C0, $0F, $85, $00, $00, $00, $00, $8B, $93, $40, $01, $00, $00, $C1, $EA, $0C, $F6, $C2, $01, $0F, $85, $00, $00, $00, $00, $3B, $2D, $00, $00, $00, $00, $74, $28, $6A, $0F, $8D, $4D, $60, $E8, $00, $00, $00, $00, $D9, $05, $00, $00, $00, $00, $DA, $E9, $DF, $E0, $F6, $C4, $44, $7A, $0F, $8B, $CD, $E8, $00, $00, $00, $00, $84, $C0, $0F, $85); SneakOver100CheckCodeMask: packed array [0 .. 81] of Byte = ($FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF); PreFuncIncreaseSkillExpSize = 56; PreFuncIncreaseSkillExpSig: packed array [0 .. 55] of Byte = ($D9, $44, $24, $08, $D9, $EE, $DE, $D9, $DF, $E0, $F6, $C4, $05, $7A, $26, $8B, $44, $24, $10, $8B, $54, $24, $0C, $6A, $00, $6A, $01, $50, $8B, $44, $24, $14, $52, $8B, $54, $24, $14, $51, $8B, $89, $18, $06, $00, $00, $89, $04, $24, $52, $E8, $00, $00, $00, $00, $C2, $10, $00); PreFuncIncreaseSkillExpMask: packed array [0 .. 55] of Byte = ($FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF); PerksAtLevelUpSize = 120; PerksAtLevelUpSig: packed array [0 .. 119] of Byte = ($80, $BE, $35, $02, $00, $00, $00, $74, $73, $8B, $0D, $00, $00, $00, $00, $8B, $89, $18, $06, $00, $00, $E8, $00, $00, $00, $00, $84, $C0, $74, $5E, $8B, $15, $00, $00, $00, $00, $8B, $0D, $00, $00, $00, $00, $6A, $01, $81, $C2, $98, $00, $00, $00, $52, $E8, $00, $00, $00, $00, $84, $C0, $75, $40, $8B, $CE, $E8, $00, $00, $00, $00, $68, $F6, $00, $00, $00, $E8, $00, $00, $00, $00, $A1, $00, $00, $00, $00, $8B, $88, $18, $06, $00, $00, $83, $C4, $04, $E8, $00, $00, $00, $00, $E8, $00, $00, $00, $00, $A1, $00, $00, $00, $00, $FE, $80, $C9, $06, $00, $00, $C6, $86, $2F, $02, $00, $00, $01, $E9); PerksAtLevelUpMask: packed array [0 .. 119] of Byte = ($FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $00, $00, $00, $00, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF); LevelUpSize = 144; LevelUpSig: packed array [0 .. 143] of Byte = ($A1, $00, $00, $00, $00, $57, $05, $8C, $00, $00, $00, $8B, $F9, $8B, $0D, $00, $00, $00, $00, $50, $E8, $00, $00, $00, $00, $84, $C0, $0F, $84, $00, $00, $00, $00, $80, $7C, $24, $08, $00, $0F, $85, $00, $00, $00, $00, $8B, $0D, $00, $00, $00, $00, $DB, $05, $00, $00, $00, $00, $64, $8B, $15, $2C, $00, $00, $00, $53, $56, $8B, $34, $8A, $8B, $0D, $00, $00, $00, $00, $8B, $9E, $AC, $04, $00, $00, $83, $C1, $60, $C7, $86, $AC, $04, $00, $00, $43, $00, $00, $00, $8B, $01, $8B, $57, $0C, $8B, $40, $14, $51, $D9, $1C, $24, $52, $FF, $D0, $83, $7F, $0C, $1A, $75, $1E, $8B, $0D, $00, $00, $00, $00, $A1, $00, $00, $00, $00, $8B, $51, $60, $8B, $52, $18, $83, $C1, $60, $51, $89, $04, $24, $6A, $20, $6A, $00, $FF, $D2); LevelUpMask: packed array [0 .. 143] of Byte = ($FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF); IncreaseLevelBySize = 25; IncreaseLevelBySig: packed array [0 .. 24] of Byte = ($8B, $44, $24, $08, $83, $F8, $01, $73, $05, $B8, $01, $00, $00, $00, $8B, $89, $18, $06, $00, $00, $89, $44, $24, $08, $E9); IncreaseLevelByMask: packed array [0 .. 24] of Byte = ($FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF); GetValueActiveLevelSize = 49; GetValueActiveLevelSig: packed array [0 .. 48] of Byte = ($A1, $00, $00, $00, $00, $83, $EC, $08, $53, $55, $8B, $6C, $24, $14, $57, $8B, $F9, $8B, $4C, $A8, $04, $8B, $51, $38, $C1, $EA, $12, $F6, $C2, $01, $74, $11, $8B, $47, $30, $85, $C0, $74, $0A, $83, $78, $30, $00, $74, $04, $B3, $01, $EB, $02); GetValueActiveLevelMask: packed array [0 .. 48] of Byte = ($FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF); GetLevelSize = 7; GetLevelSig: packed array [0 .. 6] of Byte = ($8B, $49, $24, $83, $C1, $20, $E9); GetLevelMask: packed array [0 .. 6] of Byte = ($FF, $FF, $FF, $FF, $FF, $FF, $FF); EnchantingMagnitudeSize = 155; EnchantingMagnitudeSig: packed array [0 .. 154] of Byte = ($8B, $0D, $00, $00, $00, $00, $8B, $51, $60, $8B, $42, $04, $83, $C1, $60, $53, $6A, $17, $FF, $D0, $8B, $4C, $24, $24, $83, $EC, $08, $D9, $5C, $24, $04, $89, $0C, $24, $E8, $00, $00, $00, $00, $D9, $5C, $24, $2C, $8B, $46, $24, $8B, $4E, $18, $8D, $54, $24, $2C, $52, $8B, $51, $10, $50, $A1, $00, $00, $00, $00, $52, $50, $6A, $4D, $E8, $00, $00, $00, $00, $D9, $44, $24, $40, $83, $C4, $14, $DD, $1C, $24, $E8, $00, $00, $00, $00, $8B, $56, $18, $D9, $5C, $24, $18, $D9, $44, $24, $18, $83, $C4, $08, $D9, $5C, $24, $10, $B9, $00, $00, $80, $3F, $8B, $5C, $24, $10, $89, $5C, $24, $24, $85, $D2, $0F, $00, $00, $00, $00, $00, $8B, $4A, $14, $89, $4C, $24, $10, $D9, $44, $24, $10, $D9, $44, $24, $24, $D8, $D1, $DF, $E0, $F6, $C4, $05, $7A, $06, $DD, $D9, $8B, $CB, $EB); EnchantingMagnitudeMask: packed array [0 .. 154] of Byte = ($FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF); EnchantingChargeSize = 147; EnchantingChargeSig: packed array [0 .. 146] of Byte = ($8B, $0D, $00, $00, $00, $00, $8B, $51, $60, $8B, $42, $04, $83, $C1, $60, $6A, $17, $FF, $D0, $8B, $4C, $24, $14, $83, $EC, $08, $D9, $5C, $24, $04, $89, $0C, $24, $E8, $00, $00, $00, $00, $D9, $9E, $4C, $01, $00, $00, $8B, $BE, $28, $01, $00, $00, $8B, $17, $8B, $82, $B0, $01, $00, $00, $83, $C4, $08, $8B, $CF, $FF, $D0, $D9, $7C, $24, $10, $83, $48, $04, $01, $D9, $86, $4C, $01, $00, $00, $0F, $B7, $44, $24, $10, $8B, $17, $0D, $00, $0C, $00, $00, $89, $44, $24, $20, $8B, $82, $B0, $01, $00, $00, $8B, $CF, $D9, $6C, $24, $20, $DF, $7C, $24, $20, $8B, $5C, $24, $20, $D9, $6C, $24, $10, $FF, $D0, $89, $18, $8B, $8E, $F8, $00, $00, $00, $8B, $11, $83, $7A, $08, $20, $75, $0A, $C7, $86, $4C, $01, $00, $00, $00, $00, $00, $00); EnchantingChargeMask: packed array [0 .. 146] of Byte = ($FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF);function MemCmpWithMask(Target, Source, Mask: PByte; Size: Longword): Boolean;var i: Longword;begin Result := True; try for i := 1 to Size Div 4 do begin if PLongword(Source)^ <> PLongword(Target)^ and PLongword(Mask)^ then begin Result := False; Exit; end; Inc(Target, 4); Inc(Source, 4); Inc(Mask, 4); end; for i := 1 to Size Mod 4 do begin if Source^ <> Target^ and Mask^ then begin Result := False; Exit; end; Inc(Target); Inc(Source); Inc(Mask) end; except Result := False; end;end;function BrowseMem(Target: Longword; Size: Longword): Boolean;var l: Longword;begin Result := False; if Target = 0 then Exit; for l := Target to Target + Size - 1 do begin if MemCmpWithMask(Pointer(l), @FuncIncreaseSkillExpSig, @FuncIncreaseSkillExpMask, FuncIncreaseSkillExpSize) then if @FuncIncreaseSkillExp <> nil then Exit else @FuncIncreaseSkillExp := Pointer(l) else if MemCmpWithMask(Pointer(l), @IncreaseLevelBySig, @IncreaseLevelByMask, IncreaseLevelBySize) then if IncreaseLevelBy <> nil then Exit else IncreaseLevelBy := Pointer(l) else if MemCmpWithMask(Pointer(l), @PreFuncIncreaseSkillExpSig, @PreFuncIncreaseSkillExpMask, PreFuncIncreaseSkillExpSize) then if PreFuncIncreaseSkillExp <> nil then Exit else PreFuncIncreaseSkillExp := Pointer(l) else if MemCmpWithMask(Pointer(l), @UncapSkillFormulaSig, @UncapSkillFormulaMask, UncapSkillFormulaSize) then if UncapSkillFormula <> nil then Exit else UncapSkillFormula := Pointer(l) else if MemCmpWithMask(Pointer(l), @SneakOver100CheckCodeSig, @SneakOver100CheckCodeMask, SneakOver100CheckCodeSize) then if SneakOver100CheckCode <> nil then Exit else SneakOver100CheckCode := Pointer(l) else if MemCmpWithMask(Pointer(l), @PerksAtLevelUpSig, @PerksAtLevelUpMask, PerksAtLevelUpSize) then if PerksAtLevelUp <> nil then Exit else PerksAtLevelUp := Pointer(l) else if MemCmpWithMask(Pointer(l), @LevelUpSig, @LevelUpMask, LevelUpSize) then if LevelUp <> nil then Exit else LevelUp := Pointer(l) else if MemCmpWithMask(Pointer(l), @EnchantingMagnitudeSig, @EnchantingMagnitudeMask, EnchantingMagnitudeSize) then if EnchantingMagnitude <> nil then Exit else EnchantingMagnitude := Pointer(l) else if MemCmpWithMask(Pointer(l), @EnchantingChargeSig, @EnchantingChargeMask, EnchantingChargeSize) then if EnchantingCharge <> nil then Exit else EnchantingCharge := Pointer(l) else if MemCmpWithMask(Pointer(l), @GetLevelSig, @GetLevelMask, GetLevelSize) then if @GetLevel <> nil then Exit else @GetLevel := Pointer(l) else if MemCmpWithMask(Pointer(l), @GetValueActiveLevelSig, @GetValueActiveLevelMask, GetValueActiveLevelSize) then if GetValueActiveLevel <> nil then Exit else GetValueActiveLevel := Pointer(l); end; if (@FuncIncreaseSkillExp <> nil) and (IncreaseLevelBy <> nil) and (PreFuncIncreaseSkillExp <> nil) and (UncapSkillFormula <> nil) and (SneakOver100CheckCode <> nil) and (PerksAtLevelUp <> nil) and (LevelUp <> nil) and (EnchantingMagnitude <> nil) and (EnchantingCharge <> nil) and (GetValueActiveLevel <> nil) and (@GetLevel <> nil) then Result := True else MessageBox(0, 'SKSE Community Uncapper: Unable to AutoUpdate to your current Skyrim version.', ERROR_PLUGIN, MB_ICONERROR);end;function InitOptions(AutoUpdate: Boolean = False): Boolean;const INI_ERROR = 'Error: Skyrim Community Uncapper'; IS_INVALID_VALUE = 'http://forums.bethsoft.com/topic/1342084-relskyrim-community-uncapper-previously-elys-thread-2/is not a valid value for';var Filename: String; IniFile: TMemIniFile; IniExists: Boolean; Strings: TStringList; i: Integer; NameIndex: Integer; Level: Integer; Perks: Single; MaxLevel: Integer; PreviousValue: Single; RestValue: Single; Value: Single;label Skip; function SafeReadInteger(const name: String; Default: Integer): Integer; var idx: Integer; begin Result := Default; idx := Strings.IndexOfName(Name); if (idx < 0) or TryStrToInt(Strings.ValueFromIndex[idx], Result) and (Result >= 0) and (Result <= MAX_LEVEL) then Exit; Result := Default; MessageBox(0, PChar(Strings.ValueFromIndex[idx] + IS_INVALID_VALUE + Name + '.'), INI_ERROR, MB_ICONERROR); end; function SafeReadFloat(const name: String; Default: Single): Single; var idx: Integer; begin Result := Default; idx := Strings.IndexOfName(Name); if (idx < 0) or TryStrToFloat(Strings.ValueFromIndex[idx], Result) and (Result >= 0) and (Result <= MAX_LEVEL) then Exit; Result := Default; MessageBox(0, PChar(Strings.ValueFromIndex[idx] + IS_INVALID_VALUE + Name + '.'), INI_ERROR, MB_ICONERROR); end; function SafeReadBool(const name: String; Default: Boolean): Boolean; var idx: Integer; begin Result := Default; idx := Strings.IndexOfName(Name); if (idx < 0) or TryStrToBool(Strings.ValueFromIndex[idx], Result) then Exit; Result := Default; MessageBox(0, PChar(Strings.ValueFromIndex[idx] + IS_INVALID_VALUE + Name + '.'), INI_ERROR, MB_ICONERROR); end; procedure FillEnergyTable(const name: String; var Table: TEnergyTable; ConvertToFloat: Boolean = False); var idx: Integer; j, k: Integer; Points: Integer; f: Single; begin Strings.Clear; IniFile.ReadSectionValues(Name, Strings); SetLength(Table, Strings.Count); idx := 0; For k := 0 to Strings.Count - 1 do if TryStrToInt(Strings.Names[k], Level) and (Level > 1) and (Level <= MAX_LEVEL) then if TryStrToInt(Strings.ValueFromIndex[k], Points) and (Points >= 0) and (Points <= MAX_LEVEL) then begin Table[idx].Level := Level; Table[idx].Points := Points; Inc(idx); end else MessageBox(0, PChar(Strings[k] + ' is not a correct Points value for [' + Name + '].'), INI_ERROR, MB_ICONERROR) Else MessageBox(0, PChar(Strings[k] + ' is not a correct Level value for [' + Name + '].'), INI_ERROR, MB_ICONERROR); SetLength(Table, idx); for j := High(Table) - 1 downto 1 do for k := 0 to j do if Table[k].Level > Table[k + 1].Level then begin Level := Table[k].Level; Points := Table[k].Points; Table[k].Level := Table[k + 1].Level; Table[k].Points := Table[k + 1].Points; Table[k + 1].Level := Level; Table[k + 1].Points := Points; end; If ConvertToFloat then for j := 0 to High(Table) do begin f := Table[j].Points; Table[j].Points := PLongword(@f)^; end; end; procedure ReadSectionSkillFloat(const Section: String; var Table: TSkillTable); begin Strings.Clear; IniFile.ReadSectionValues(Section, Strings); Table[AlterationID] := SafeReadFloat('fAlteration', 1); Table[ArcheryID] := SafeReadFloat('fArchery', 1); Table[AlchemyID] := SafeReadFloat('fAlchemy', 1); Table[ConjurationID] := SafeReadFloat('fConjuration', 1); Table[BlockID] := SafeReadFloat('fBlock', 1); Table[LightArmorID] := SafeReadFloat('fLightArmor', 1); Table[DestructionID] := SafeReadFloat('fDestruction', 1); Table[HeavyArmorID] := SafeReadFloat('fHeavyArmor', 1); Table[LockpickingID] := SafeReadFloat('fLockpicking', 1); Table[EnchantingID] := SafeReadFloat('fEnchanting', 1); Table[OneHandedID] := SafeReadFloat('fOneHanded', 1); Table[PickpocketID] := SafeReadFloat('fPickpocket', 1); Table[IllusionID] := SafeReadFloat('fIllusion', 1); Table[SmithingID] := SafeReadFloat('fSmithing', 1); Table[SneakID] := SafeReadFloat('fSneak', 1); Table[RestorationID] := SafeReadFloat('fRestoration', 1); Table[TwoHandedID] := SafeReadFloat('fTwoHanded', 1); Table[SpeechID] := SafeReadFloat('fSpeech', 1); end; procedure ReadSectionSkillInt(const Section: String; var Table: TSkillTable); begin Strings.Clear; IniFile.ReadSectionValues(Section, Strings); Table[AlterationID] := SafeReadInteger('iAlteration', 100); Table[ArcheryID] := SafeReadInteger('iArchery', 100); Table[AlchemyID] := SafeReadInteger('iAlchemy', 100); Table[ConjurationID] := SafeReadInteger('iConjuration', 100); Table[BlockID] := SafeReadInteger('iBlock', 100); Table[LightArmorID] := SafeReadInteger('iLightArmor', 100); Table[DestructionID] := SafeReadInteger('iDestruction', 100); Table[HeavyArmorID] := SafeReadInteger('iHeavyArmor', 100); Table[LockpickingID] := SafeReadInteger('iLockpicking', 100); Table[EnchantingID] := SafeReadInteger('iEnchanting', 100); Table[OneHandedID] := SafeReadInteger('iOneHanded', 100); Table[PickpocketID] := SafeReadInteger('iPickpocket', 100); Table[IllusionID] := SafeReadInteger('iIllusion', 100); Table[SmithingID] := SafeReadInteger('iSmithing', 100); Table[SneakID] := SafeReadInteger('iSneak', 100); Table[RestorationID] := SafeReadInteger('iRestoration', 100); Table[TwoHandedID] := SafeReadInteger('iTwoHanded', 100); Table[SpeechID] := SafeReadInteger('iSpeech', 100); end;begin Result := True; SetLength(Filename, MAX_PATH + 1); GetModuleFileNameW(HInstance, @Filename[1], MAX_PATH + 1); Filename := ExtractFilePath(Filename) + 'SKSE_Elys_Uncapper.ini'; IniExists := FileExists(Filename); if not IniExists then MessageBox(0, '.\Data\SKSE\Plugins\SKSE_Elys_Uncapper.ini file not found.', 'Warning: Skyrim Community Uncapper', MB_ICONWARNING); IniFile := TMemIniFile.Create(Filename); try Strings := TStringList.Create; try FormatSettings.DecimalSeparator := '.'; SetLength(TrueBoolStrs, 2); TrueBoolStrs[0] := 'True'; TrueBoolStrs[1] := '1'; SetLength(FalseBoolStrs, 2); FalseBoolStrs[0] := 'False'; FalseBoolStrs[1] := '0'; IniFile.ReadSectionValues('General', Strings); iIniFileVersion := SafeReadInteger('iIniFileVersion', 0); bEnabled := SafeReadBool('bEnabled', False); bAutoUpdate := SafeReadBool('bAutoUpdate', False); if AutoUpdate then begin if bAutoUpdate = True then Result := True else begin MessageBox(0, PChar('SKSE Community Uncapper only supports Skyrim Version 1.5.26.'#13#10'You can enable the AutoUpdate functionality by setting bAutoUpdate=1 inside the SKSE_Elys_Uncapper.ini file.'), ERROR_PLUGIN, MB_ICONERROR); Result := False; end; Exit; end; bUseSkillFormulaCaps := SafeReadBool('bUseSkillFormulaCaps', False); bUseSkillCaps := SafeReadBool('bUseSkillCaps', False); bUseSkillExpGainMults := SafeReadBool('bUseSkillExpGainMults', False); bUsePCLevelSkillExpMults := SafeReadBool('bUsePCLevelSkillExpMults', False); bUsePerksAtLevelUp := SafeReadBool('bUsePerksAtLevelUp', False); bUseHealthAtLevelUp := SafeReadBool('bUseHealthAtLevelUp', False); bUseMagickaAtLevelUp := SafeReadBool('bUseMagickaAtLevelUp', False); bUseStaminaAtLevelUp := SafeReadBool('bUseStaminaAtLevelUp', False); bUseCarryWeightAtHealthLevelUp := SafeReadBool('bUseCarryWeightAtHealthLevelUp', False); bUseCarryWeightAtMagickaLevelUp := SafeReadBool('bUseCarryWeightAtMagickaLevelUp', False); bUseCarryWeightAtStaminaLevelUp := SafeReadBool('bUseCarryWeightAtStaminaLevelUp', False); bUseEnchanterCaps := SafeReadBool('bUseEnchanterCaps', False); if bUseSkillCaps then ReadSectionSkillInt('SkillCaps', SkillCaps); if bUseSkillFormulaCaps then ReadSectionSkillInt('SkillFormulaCaps', SkillFormulaCaps); if bUseSkillExpGainMults then ReadSectionSkillFloat('SkillExpGainMults', SkillExpGainMults); if bUsePCLevelSkillExpMults then ReadSectionSkillFloat('PCLevelSkillExpMults', PCLevelSkillExpMults); if bUsePerksAtLevelUp then begin Strings.Clear; IniFile.ReadSectionValues('PerksAtLevelUp', Strings); MaxLevel := 1; For i := 0 to Strings.Count - 1 do if TryStrToInt(Strings.Names[i], Level) and (Level > 1) and (Level <= MAX_LEVEL) then if TryStrToFloat(Strings.ValueFromIndex[i], Perks) and (Perks >= 0) and (Perks <= 255) then begin if Level > MaxLevel then MaxLevel := Level; end else MessageBox(0, PChar(Strings[i] + ' is not a correct Perks value for [PerksAtLevelUp].'), INI_ERROR, MB_ICONERROR) else MessageBox(0, PChar(Strings[i] + ' is not a correct Level value for [PerksAtLevelUp].'), INI_ERROR, MB_ICONERROR); PreviousValue := 1; RestValue := 0; if MaxLevel > 1 then begin for i := 2 to MaxLevel do begin NameIndex := Strings.IndexOfName(IntToStr(i)); if (NameIndex >= 0) and TryStrToFloat(Strings.ValueFromIndex[NameIndex], Perks) and (Perks >= 0) and (Perks <= 255) then begin Value := Perks + RestValue; PerksTable[i] := Int(Value); PreviousValue := Perks; RestValue := Frac(Value); end else begin Value := PreviousValue + RestValue; PerksTable[i] := Int(Value); RestValue := Frac(Value); end; end; end; for i := MaxLevel + 1 to MAX_LEVEL do begin PerksTable[i] := Int(PreviousValue + RestValue); RestValue := Frac(PreviousValue + RestValue); end; end; if bUseHealthAtLevelUp then FillEnergyTable('HealthAtLevelUp', HealthAtLevelUp); if bUseMagickaAtLevelUp then FillEnergyTable('MagickaAtLevelUp', MagickaAtLevelUp); if bUseStaminaAtLevelUp then FillEnergyTable('StaminaAtLevelUp', StaminaAtLevelUp); if bUseCarryWeightAtHealthLevelUp then FillEnergyTable('CarryWeightAtHealthLevelUp', CarryWeightAtHealthLevelUp, True); if bUseCarryWeightAtMagickaLevelUp then FillEnergyTable('CarryWeightAtMagickaLevelUp', CarryWeightAtMagickaLevelUp, True); if bUseCarryWeightAtStaminaLevelUp then FillEnergyTable('CarryWeightAtStaminaLevelUp', CarryWeightAtStaminaLevelUp, True); if bUseEnchanterCaps then begin Strings.Clear; IniFile.ReadSectionValues('EnchanterCaps', Strings); iMaxEnchantingLevelForMagnitude := SafeReadInteger('iMaxEnchantingLevelForMagnitude', 199); iMaxEnchantingLevelForCharges := SafeReadInteger('iMaxEnchantingLevelForCharges', 199); end; Skip: finally Strings.Free; end; except MessageBox(0, 'SKSE Community Uncapper encountered an error while attempting to read SKSE_Elys_Uncapper.ini.', ERROR_PLUGIN, MB_ICONERROR); Result := False; end; IniFile.Free;end;Function SKSEPlugin_Query(const skse: SKSEInterface; var Info: PluginInfo): Boolean; cdecl;begin Info.infoVersion := PluginInfo.kInfoVersion; Info.name := 'SKSE_Elys_Uncapper'; Info.version := PLUGIN_VER; Result := False; if skse.skseVersion < SKSE_VER then begin MessageBox(0, 'SKSE Community Uncapper requires SKSE Version 1.4.8 or above.', ERROR_PLUGIN, MB_ICONERROR); Exit; end; if skse.isEditor <> 0 then Exit; if skse.runtimeVersion <> SKYRIM_VER then if not InitOptions(True) then Exit; Result := True;end;Function SKSEPlugin_Load(const skse: SKSEInterface): Boolean; cdecl;var p: Pointer; ExeMemory: TExeMemory;begin Result := False; If not InitOptions then Exit; if iIniFileVersion <> INI_VER then MessageBox(0, 'SKSE_Elys_Uncapper.ini: Incorrect file version.', 'Warning: Skyrim Community Uncapper', MB_ICONWARNING); if not bEnabled then begin Result := True; Exit; end; if skse.runtimeVersion = SKYRIM_VER then begin @FuncIncreaseSkillExp := Pointer($00753A30); IncreaseLevelBy := Pointer($0072A030); PreFuncIncreaseSkillExp := Pointer($00729FF0); UncapSkillFormula := Pointer($005AA140); SneakOver100CheckCode := Pointer($006C8C7A); PerksAtLevelUp := Pointer($0087E90F); LevelUp := Pointer($0085E0B0); EnchantingMagnitude := Pointer($00840645); EnchantingCharge := Pointer($008432E1); @GetLevel := Pointer($0069FC40); GetValueActiveLevel := Pointer($006D7760); end else if bAutoUpdate then begin ExeMemory := GetExeMemory; if not BrowseMem(ExeMemory.Address, ExeMemory.Size) then Exit; end Else Exit; if bUseSkillCaps then begin @GetSkillCoefficients := Pointer(Longword(@FuncIncreaseSkillExp) + $80 + PLongword(Longword(@FuncIncreaseSkillExp) + $7C)^); @CalculateExpForNextLevel := Pointer(Longword(@FuncIncreaseSkillExp) + $216 + PLongword(Longword(@FuncIncreaseSkillExp) + $212)^); if not SetRelCall(PByte(@FuncIncreaseSkillExp) + $3B, @SkillCapPatch, 1) or // Skill Cap not SetRelCall(PByte(@FuncIncreaseSkillExp) + $13D, @SkillCapPatch, 1) or // Skill Cap not SetRelCall(PByte(@FuncIncreaseSkillExp) + $259, @SkillCapPatch, 1) or // Skill Cap not SetRelCall(PByte(@CalculateExpForNextLevel) + 7, @SkillCapPatch, 1) then // Skill Cap Exit; end; if bUseSkillCaps or bUseSkillExpGainMults or bUsePCLevelSkillExpMults then begin if not SetRelCall(PreFuncIncreaseSkillExp + $30, @MyFuncIncreaseSkillExp) or // Increase Skill Exp Hook not SetRelJmp(IncreaseLevelBy, @MyIncreaseSkillLevelBy) then // IncPCS, Trainer fix Exit; end; if bUsePCLevelSkillExpMults then begin @SkillToCharacterExp := Pointer(Longword(@FuncIncreaseSkillExp) + $22B + PLongword(Longword(@FuncIncreaseSkillExp) + $227)^); if not SetRelCall(PByte(@FuncIncreaseSkillExp) + $226, @MySkillToCharacterExp) then Exit; end; if bUseSkillFormulaCaps then begin @GetValueActiveLevelHooked := GetValueActiveLevel + $05; SkillTableAddr := PLongword(PByte(@GetValueActiveLevelHooked) - 4)^; p := @fMax_Level; if not SetRelJmp(PByte(@GetValueActiveLevelHooked) - 5, @MyGetValueActiveLevel) or // Cap Formula caps.} not Overwrite(UncapSkillFormula + $29, @p, 4) or // Uncap Skill formula caps over 100 not Overwrite(SneakOver100CheckCode + $40, @FixSneakOver100CheckCode, 6) then // Sneak >100 Formula Fix Exit; end; if bUsePerksAtLevelUp then if not SetRelCall(PerksAtLevelUp + $6A, @IncreasePerkPool, 1) then Exit; if bUseHealthAtLevelUp or bUseMagickaAtLevelUp or bUseStaminaAtLevelUp then begin pPlayer := Pointer(Pointer(LevelUp + $46)^); piAVDhmsLevelUp := PInteger(Pointer(LevelUp + $34)^); if not SetRelCall(LevelUp + $32, @IncreaseEnergy, 1) then Exit; end; if bUseCarryWeightAtHealthLevelUp or bUseCarryWeightAtMagickaLevelUp or bUseCarryWeightAtStaminaLevelUp then begin pPlayer := Pointer(Pointer(LevelUp + $46)^); pfLevelUpCarryWeightMod := PSingle(Pointer(LevelUp + $79)^); if not Overwrite(LevelUp + $71, @Zero, 1) or not SetRelCall(LevelUp + $78, @IncreaseCarryWeight) then Exit; end; if bUseEnchanterCaps then begin @GetValueActiveLevelHooked := GetValueActiveLevel + $05; if not SetRelCall(EnchantingMagnitude + $0F, @EnchantingMagnitudeFix) or not SetRelCall(EnchantingCharge + $0C, @EnchantingChargeFix, 2) then Exit; end; Result := True;end;exports SKSEPlugin_Query, SKSEPlugin_Load;beginend.
http://skyrim.nexusmods.com/downloads/file.php?id=1175