private void ApplyGuardians() { if (Guardians == null || Guardians.Length != 2) { throw new Exception("2 guardians must be used"); } int startIndexGuardians = UPKFile.FindBytesKMP(SpitfireGameUPK.HeroObjectGuardiansHeader, SpitfireGameUPK.HeroObjects[Name].Offset, SpitfireGameUPK.HeroObjects[Name].Size); if (startIndexGuardians == -1) { // Get position after Loadout and Add Header and Field Type startIndexGuardians = UPKFile.FindBytesKMP(SpitfireGameUPK.HeroObjectLoadoutHeader, SpitfireGameUPK.HeroObjects[Name].Offset, SpitfireGameUPK.HeroObjects[Name].Size) + LoadoutSectionLength; UPKFile.OverrideBytes(SpitfireGameUPK.HeroObjectGuardiansHeader, startIndexGuardians); UPKFile.OverrideBytes(SpitfireGameUPK.HeroObjectGuardiansFieldType, startIndexGuardians + SpitfireGameUPK.HeroObjectGuardiansHeader.Length); } int endIndex = UPKFile.FindBytesKMP(StartHeaderAfterGuardians, startIndexGuardians + GuardiansOffset, SpitfireGameUPK.HeroObjects[Name].Size); int totalSize = endIndex - (startIndexGuardians + GuardiansArrayElementCountOffset); // Everything after header int guardiansArraySizeIndex = startIndexGuardians + GuardiansArraySizeOffset; int guardiansArrayElementCountIndex = startIndexGuardians + GuardiansArrayElementCountOffset; int guardiansIndex = startIndexGuardians + GuardiansOffset; byte[] firstGuardian = Resources.Loadout.Guardians[Guardians[0]].First; // Extra space after each guardian is already included byte[] secondGuardian = Resources.Loadout.Guardians[Guardians[1]].First; byte[] sizeFirstGuardian = new byte[] { Resources.Loadout.Guardians[Guardians[0]].Second, 0x00, 0x00, 0x00 }; // Add the 0x00 to complete the 4 bytes field int secondGuardianOffset = firstGuardian.Length + sizeFirstGuardian.Length + GuardiansOffset + 4; // 4 from second guardian size itself byte[] sizeSecondGuardian = new byte[] { (byte)(totalSize - secondGuardianOffset), 0x00, 0x00, 0x00 }; // Counting extra space int emptySpaceOffset = secondGuardianOffset + Resources.Loadout.Guardians[Guardians[1]].Second; byte[] emptySpace = Enumerable.Repeat((byte)0x00, totalSize - emptySpaceOffset).ToArray(); // Combining arrays to SizeGuardian1 + Guardian1 + SizeGuardian2 + Guardian2 + emptySpace byte[] guardiansBytes = sizeFirstGuardian.Concat(firstGuardian).Concat(sizeSecondGuardian).Concat(secondGuardian).Concat(emptySpace).ToArray(); UPKFile.OverrideBytes(guardiansBytes, guardiansIndex); UPKFile.OverrideSingleByte((byte)totalSize, guardiansArraySizeIndex); // Size (counts array element count and both guardians and their sizes but not itself or index so -8) //TODO check single byte and avoid override? UPKFile.OverrideSingleByte(GuardianSlotsNumber, guardiansArrayElementCountIndex); // Array Element Count }
private void ApplyTrapsGear() { if (Loadout == null || Loadout.Length != LoadoutSlotsNumber) { throw new Exception("9 traps/gear must be used"); } int startIndexLoadout = UPKFile.FindBytesKMP(SpitfireGameUPK.HeroObjectLoadoutHeader, SpitfireGameUPK.HeroObjects[Name].Offset, SpitfireGameUPK.HeroObjects[Name].Size - UPKFile.nBytesRemoved); if (startIndexLoadout == -1) { // Get position after Archetype and Add Header and Field Type startIndexLoadout = UPKFile.FindBytesKMP(SpitfireGameUPK.HeroObjectDefaultInventoryArchetypesHeader, SpitfireGameUPK.HeroObjects[Name].Offset, SpitfireGameUPK.HeroObjects[Name].Size) + SpitfireGameUPK.HeroObjectDefaultInventoryArchetypesSectionLength; UPKFile.InsertZeroedBytes(startIndexLoadout, LoadoutSectionLength); UPKFile.OverrideBytes(SpitfireGameUPK.HeroObjectLoadoutHeader, startIndexLoadout); UPKFile.OverrideBytes(SpitfireGameUPK.HeroObjectLoadoutFieldType, startIndexLoadout + SpitfireGameUPK.HeroObjectLoadoutHeader.Length); } int arraySizeIndex = startIndexLoadout + LoadoutArraySizeOffset; int arrayElementCountIndex = startIndexLoadout + LoadoutArrayElementCountOffset; int loadoutSlotsIndex = startIndexLoadout + LoadoutSlotsOffset; // IF there aren't 9 slots set up we create them and insert necessary bytes int loadoutSlotsUsed = UPKFile.GetByte(arrayElementCountIndex); if (loadoutSlotsUsed != LoadoutSlotsNumber) { UPKFile.OverrideSingleByte((LoadoutSlotsNumber + 1) * LoadoutSlotByteSize, arraySizeIndex); // Array Size (+1 to count the size field itself too) UPKFile.OverrideSingleByte(LoadoutSlotsNumber, arrayElementCountIndex); // Array Element Count ( the 4 bytes inbetween are "index 0") // Add new slots (as many as missing) int indexAfterUsedSlots = loadoutSlotsIndex + (loadoutSlotsUsed * LoadoutSlotByteSize); UPKFile.InsertZeroedBytes(indexAfterUsedSlots, (LoadoutSlotsNumber - loadoutSlotsUsed) * LoadoutSlotByteSize); } // Convert and apply Loadout byte[] loadoutBytes = ConvertLoadoutToBytes(Loadout); UPKFile.OverrideBytes(loadoutBytes, loadoutSlotsIndex); }
private void ApplySkin() { int startIndexSkin = UPKFile.FindBytesKMP(SpitfireGameUPK.HeroObjectCurrentSkinClassHeader, SpitfireGameUPK.HeroObjects[Name].Offset, SpitfireGameUPK.HeroObjects[Name].Size); UPKFile.OverrideBytes(GameInfo.Heroes[Name].GetSkinHex(Skin), startIndexSkin + SkinOffsetFromHeader); }