예제 #1
0
        public static byte[] GetTeamSizes()
        {
            var bdPointer1 = OffsetScanner.GetOffset(GameOffset.FFX_BlitzballTeamData);
            var bdPointer2 = GameMemory.Read <int>(bdPointer1, false);
            var bdPointer  = GameMemory.Read <int>(bdPointer2 + 0x2C, false);

            return(GameMemory.Read <byte>(bdPointer + 0xA88, 6, false));
        }
예제 #2
0
        public static void SetTeamSize(int teamIndex, byte teamSize)
        {
            var bdPointer1 = OffsetScanner.GetOffset(GameOffset.FFX_BlitzballTeamData);
            var bdPointer2 = GameMemory.Read <int>(bdPointer1, false);
            var bdPointer  = GameMemory.Read <int>(bdPointer2 + 0x2C, false);

            GameMemory.Write(bdPointer + 0xA88 + teamIndex, teamSize, false);
        }
예제 #3
0
        private void ButtonMax_Click(object sender, RoutedEventArgs e)
        {
            var charOffset  = _offsetPartyStats + _characterIndex * _sizePartyMember;
            var levelOffset = (int)Marshal.OffsetOf <PartyMember>("OverdriveLevel") + charOffset;
            var currentMax  = GameMemory.Read <byte>(levelOffset, 2, false);

            GameMemory.Write <byte>(levelOffset, currentMax[1], false);
            Refresh(_characterIndex);
        }
예제 #4
0
        private void UpdateSharedAPState()
        {
            var gainedAp = GameMemory.Read <byte>(_offsetGainedAp, 8);

            for (int i = 0; i < 8; i++)
            {
                var box = (CheckBox)ShareBoxes.Children[i];
                _sharedApState[i] = box.IsChecked.Value ? (byte)1 : gainedAp[i];
            }
        }
예제 #5
0
        private void KeyItemButtonsOnButtonClicked(int buttonIndex)
        {
            var keyItemData  = GameMemory.Read <byte>(_offsetKeyItem, 8, false);
            var bitIndex     = KeyItem.KeyItems[buttonIndex].BitIndex;
            var keyByteIndex = bitIndex / 8;
            var keyBitIndex  = bitIndex % 8;

            keyItemData[keyByteIndex] = BitHelper.ToggleBit(keyItemData[keyByteIndex], keyBitIndex);
            GameMemory.Write(_offsetKeyItem, keyItemData, false);
            Refresh();
        }
예제 #6
0
        public static string GetName(int partyIndex)
        {
            if (partyIndex < 8)
            {
                return(null);
            }
            var offset    = _offsetAeonNames + 0xA0 + AeonNames[partyIndex - 8];
            var nameBytes = GameMemory.Read <byte>(offset, 8, false);

            return(StringConverter.ToString(nameBytes));
        }
예제 #7
0
        public static int GetEntityOffset(EntityType entityType, int entityIndex)
        {
            var pointerOffset = entityType == EntityType.Party ? OffsetPtrParty : OffsetPtrEnemy;
            var ptrEntityList = GameMemory.Read <IntPtr>(pointerOffset, false);

            if (ptrEntityList == IntPtr.Zero)
            {
                return(0);
            }

            return((int)ptrEntityList + (int)Battle.BlockLengthEntity * entityIndex);
        }
예제 #8
0
        public void Refresh()
        {
            _refreshing = true;
            var nameBytes = LegacyMemoryReader.ReadBytes(_offsetCreatureName + (_creatureIndex * 40), 18);
            var name      = StringConverter.ToASCII(nameBytes);

            CreatureName.Text          = name;
            CreatureSize.SelectedIndex = GameMemory.Read <byte>(_statsOffset + (int)Offsets.StatOffsets.Size) - 1;
            _statsPanel.Refresh(_creatureIndex + 15);
            _creatureAbilities.Refresh();
            _refreshing = false;
        }
예제 #9
0
        public void Refresh()
        {
            _refreshing   = true;
            _editingItem  = -1;
            _currentItems = Item.ReadItems();

            // Refresh inventory items
            for (int i = 0; i < _currentItems.Length; i++)
            {
                if (_currentItems[i].ID == 0xFF)
                {
                    // Empty slot
                    _itemButtons.SetContent(i, "< EMPTY >");
                }
                else
                {
                    // Show item name and count
                    _itemButtons.SetContent(i, _currentItems[i].Name + " x" + _currentItems[i].Count);
                }
            }

            // Refresh key items and al bhed dictionaries
            var keyItemData = GameMemory.Read <byte>(_offsetKeyItem, 8, false);
            var alBhedData  = GameMemory.Read <byte>(_offsetAlBhed, 4, false);

            _keyItemState = BitHelper.GetBitArray(keyItemData, 58);
            _alBhedState  = BitHelper.GetBitArray(alBhedData, 26);

            // Key Items
            for (int i = 0; i < KeyItem.KeyItems.Length - 1; i++)
            {
                if (_keyItemState[KeyItem.KeyItems[i].BitIndex])
                {
                    // Key item owned
                    _keyItemButtons.Buttons[i].Foreground = _trueKeyItemBrush;
                    _keyItemButtons.SetContent(i, $"{KeyItem.KeyItems[i].Name}");
                }
                else
                {
                    // Key item not owned
                    _keyItemButtons.Buttons[i].Foreground = _falseKeyItemBrush;
                    _keyItemButtons.SetContent(i, $"{KeyItem.KeyItems[i].Name}");
                }
            }

            // Al Bhed Dictionaries
            for (int i = 0; i < 26; i++)
            {
                (PanelAlBhed.Children[i] as CheckBox).IsChecked = _alBhedState[i];
            }
            _refreshing = false;
        }
예제 #10
0
        public static void ToggleOverdriveMode(int charIndex, int overdriveId)
        {
            var odOffset = StructHelper.GetFieldOffset <PartyMember>("OverdriveModes",
                                                                     _offsetParty + Marshal.SizeOf <PartyMember>() * charIndex);
            var odBytes = GameMemory.Read <byte>(odOffset, 3, false);

            var odMode = OverdriveModes.First(od => od.ID == overdriveId);

            var bitIndex  = odMode.BitIndex % 8;
            var byteIndex = odMode.BitIndex / 8;

            odBytes[byteIndex] = BitHelper.ToggleBit(odBytes[byteIndex], bitIndex);

            GameMemory.Write(odOffset, odBytes, false);
        }
예제 #11
0
    public static bool ValidateBytes()
    {
        var codeBytes1 = GameMemory.Read <byte>(_offsetModBytes1, _originalBytes1.Length);
        var codeBytes2 = GameMemory.Read <byte>(_offsetModBytes2, _originalBytes2.Length);

        if ((codeBytes1.SequenceEqual(_originalBytes1) &&
             codeBytes2.SequenceEqual(_originalBytes2)) ||
            (codeBytes1.SequenceEqual(_modBytes) &&
             codeBytes2.SequenceEqual(_modBytes)))
        {
            return(true);
        }
        ModLogger.WriteLine("Unexpected assembly code, aborting code write.");
        return(false);
    }
예제 #12
0
        public void Refresh(int characterIndex)
        {
            _refreshing     = true;
            _characterIndex = characterIndex;

            var totalOverdrives = OverdriveMode.OverdriveModes.Length;

            var charOffset = _offsetPartyStats + _characterIndex * _sizePartyMember;

            var offsetLevels   = (int)Marshal.OffsetOf <PartyMember>("OverdriveMode") + charOffset;
            var offsetFlags    = (int)Marshal.OffsetOf <PartyMember>("OverdriveModes") + charOffset;
            var offsetCounters = (int)Marshal.OffsetOf <PartyMember>("OverdriveWarrior") + charOffset;

            var odLevels   = GameMemory.Read <byte>(offsetLevels, 3, false);
            var odBytes    = GameMemory.Read <byte>(offsetFlags, 3, false);
            var odCounters = GameMemory.Read <byte>(offsetCounters, totalOverdrives * 2, false);

            ComboCurrentOverdrive.SelectedIndex = odLevels[0];
            TextOverdriveCurrent.Text           = odLevels[1].ToString();
            TextOverdriveMax.Text = odLevels[2].ToString();

            var learnedOverdrives = BitHelper.GetBitArray(odBytes, totalOverdrives);

            for (int i = 0; i < totalOverdrives; i++)
            {
                var dockPanel = GridOverdrive.Children[i] as DockPanel;
                if (dockPanel == null)
                {
                    continue;
                }

                var checkLearned = (dockPanel.Children[0] as CheckBox);
                var textCount    = (dockPanel.Children[1] as TextBox);

                if (checkLearned != null)
                {
                    checkLearned.IsChecked = learnedOverdrives[OverdriveMode.OverdriveModes[i].BitIndex];
                }
                if (textCount != null)
                {
                    textCount.Text =
                        BitConverter.ToUInt16(odCounters, OverdriveMode.OverdriveModes[i].BitIndex * 2).ToString();
                }
            }


            _refreshing = false;
        }
예제 #13
0
        public static Character[] GetActiveParty()
        {
            var party = GameMemory.Read <byte>(_offsetPartyList, 8, false);

            if (party == null)
            {
                return(new Character[8]);
            }
            var outArray = new Character[8];

            for (int i = 0; i < 8; i++)
            {
                outArray[i] = (Character)party[i];
            }

            return(outArray);
        }
예제 #14
0
        public static EquipmentItem[] ReadItems()
        {
            var dataLength = MaxItems * BlockLength;
            var dataBytes  = GameMemory.Read <byte>(Offset, dataLength, false);

            var readItems = new EquipmentItem[MaxItems];

            for (int i = 0; i < MaxItems; i++)
            {
                IntPtr ptrEquipmentData = Marshal.AllocHGlobal(dataLength);
                Marshal.Copy(dataBytes, i * BlockLength, ptrEquipmentData, BlockLength);
                readItems[i] = (EquipmentItem)Marshal.PtrToStructure(ptrEquipmentData, typeof(EquipmentItem));
                Marshal.FreeHGlobal(ptrEquipmentData);
            }

            return(readItems);
        }
예제 #15
0
    public void Update()
    {
        if (!_modActive)
        {
            return;
        }

        updateTicks++;
        if (updateTicks < 50)
        {
            return;                   // tick every ~400ms, faster and the game misses the flag on room change
        }
        updateTicks = 0;

        var battlePointer = GameMemory.Read <int>(offsetBattlePointer);

        if (battlePointer == 0) // Not in battle, enable camera
        {
            // Check current room
            var currentRoom = GameMemory.Read <ushort>(offsetCurrentRoom);

            // Check if room is on banned rooms list
            if (Array.IndexOf(bannedRooms, currentRoom) != -1)
            {
                GameMemory.Write <byte>(offsetCameraFlag, 0);
                lastRoom = currentRoom;
                return;
            }

            // If we have changed rooms, reset flag this tick
            if (currentRoom != lastRoom)
            {
                ModLogger.WriteLine("Room change detected: {0}", currentRoom.ToString("X2"));
                GameMemory.Write <byte>(offsetCameraFlag, 0);
                lastRoom = currentRoom;
                return;
            }

            // Enable camera flag
            GameMemory.Write <byte>(offsetCameraFlag, 1);
        }
        else // In battle, disable camera
        {
            GameMemory.Write <byte>(offsetCameraFlag, 0);
        }
    }
예제 #16
0
        private void AlBhedDictionary_CheckedChanged(object sender, RoutedEventArgs e)
        {
            if (_refreshing)
            {
                return;
            }
            var checkBox   = sender as CheckBox;
            var alBhedData = GameMemory.Read <byte>(_offsetAlBhed, 4, false);

            var boxIndex = PanelAlBhed.Children.IndexOf(checkBox);

            var byteIndex = boxIndex / 8;
            var bitIndex  = boxIndex % 8;

            alBhedData[byteIndex] = BitHelper.ToggleBit(alBhedData[byteIndex], bitIndex);
            GameMemory.Write(_offsetAlBhed, alBhedData, false);
            Refresh();
        }
예제 #17
0
        public static SphereGridNode ReadNode(int nodeIndex)
        {
            var offset    = _offsetSphereGrid + 0x818 + nodeIndex * _sizeSphereGridNode;
            var nodeBytes = GameMemory.Read <byte>(offset, _sizeSphereGridNode, false);

            var nodePtr = Marshal.AllocHGlobal(_sizeSphereGridNode);

            try
            {
                Marshal.Copy(nodeBytes, 0, nodePtr, _sizeSphereGridNode);
                var node = Marshal.PtrToStructure <SphereGridNode>(nodePtr);
                return(node);
            }
            finally
            {
                Marshal.FreeHGlobal(nodePtr);
            }
        }
예제 #18
0
        public static PartyMember ReadPartyMember(int partyIndex)
        {
            // Read an item from the game's memory into struct
            var offset = _offsetParty + partyIndex * _blockLength;
            var bytes  = GameMemory.Read <byte>(offset, _blockLength, false);

            IntPtr ptrEquipmentItem = Marshal.AllocHGlobal(_blockLength);

            try
            {
                // Attempt to copy memory bytes into struct and return
                Marshal.Copy(bytes, 0, ptrEquipmentItem, _blockLength);
                return((PartyMember)Marshal.PtrToStructure(ptrEquipmentItem, typeof(PartyMember)));
            }
            finally
            {
                Marshal.FreeHGlobal(ptrEquipmentItem);
            }
        }
예제 #19
0
        public static EquipmentItem ReadItem(int itemIndex)
        {
            // Read an item from the game's memory into struct
            var offset = Offset + itemIndex * BlockLength;
            var bytes  = GameMemory.Read <byte>(offset, BlockLength, false);

            IntPtr ptrEquipmentItem = Marshal.AllocHGlobal(BlockLength);

            try
            {
                // Attempt to copy memory bytes into struct and return
                Marshal.Copy(bytes, 0, ptrEquipmentItem, BlockLength);
                return((EquipmentItem)Marshal.PtrToStructure(ptrEquipmentItem, typeof(EquipmentItem)));
            }
            finally
            {
                Marshal.FreeHGlobal(ptrEquipmentItem);
            }
        }
예제 #20
0
        public static BlitzballData ReadBlitzballData(bool dumpBytes = false)
        {
            var offsetOfPrizes = (int)Marshal.OffsetOf <BlitzballData>("BlitzballPrizes");
            var blitzBytes     = GameMemory.Read <byte>(_dataPointer, _blitzDataSize, false);

            if (dumpBytes)
            {
                File.WriteAllBytes($"blitzdata_{DateTime.Now.Millisecond.ToString()}.bin", blitzBytes);
            }

            var blitzPtr = Marshal.AllocHGlobal(blitzBytes.Length);

            try
            {
                Marshal.Copy(blitzBytes, 0, blitzPtr, blitzBytes.Length);
                return((BlitzballData)Marshal.PtrToStructure(blitzPtr, typeof(BlitzballData)));
            }
            finally
            {
                Marshal.FreeHGlobal(blitzPtr);
            }
        }
예제 #21
0
파일: Item.cs 프로젝트: redthefed/Farplane
        public static Item[] ReadItems()
        {
            var itemData  = GameMemory.Read <byte>(_offsetItemTypes, TotalItems * 2, false);
            var countData = GameMemory.Read <byte>(_offsetItemCounts, TotalItems, false);

            var itemList = new List <Item>();

            for (int i = 0; i < TotalItems; i++)
            {
                var itemID    = BitConverter.ToInt16(itemData, i * 2);
                var itemCount = countData[i];
                var item      = FromID(itemID);
                itemList.Add(new Item()
                {
                    ID    = itemID,
                    Name  = item == null ? string.Empty : item.Name,
                    Count = itemCount
                });
            }

            return(itemList.ToArray());
        }
예제 #22
0
        public KernelTable(int startOffset)
        {
            // Read kernel header
            _kernelHeader = GameMemory.Read <KernelFileHeader>(startOffset, false);

            // Read block data
            _dataBlock = GameMemory.Read <byte>(startOffset + 0x10, _kernelHeader.DataLength, false);

            // Calculate string table length
            var stringTableLength = 0;

            // Find the last referenced string offset
            for (int i = 0; i < BlockCount; i++)
            {
                var blockOffset = i * _kernelHeader.BlockLength;
                var string1     = BitConverter.ToInt16(_dataBlock, blockOffset + stringOffset1);
                var string2     = BitConverter.ToInt16(_dataBlock, blockOffset + stringOffset2);

                if (string1 > stringTableLength)
                {
                    stringTableLength = string1;
                }
                if (string2 > stringTableLength)
                {
                    stringTableLength = string2;
                }
            }

            // Add length of last string to table length
            var lastString       = GameMemory.Read <byte>(startOffset + _kernelHeader.DataLength + 0x14 + stringTableLength, 512, false);
            var lastStringLength = Array.IndexOf(lastString, (byte)0) + 3; // for 0x004700 end string marker

            stringTableLength += lastStringLength;

            // Read string table
            _stringTable = GameMemory.Read <byte>(startOffset + _kernelHeader.DataLength + 0x14, stringTableLength, false);
        }
예제 #23
0
        public static int GetSelectedNode()
        {
            var selectedNode = GameMemory.Read <int>(_offsetCurrentNode, false);

            return(selectedNode);
        }
예제 #24
0
        public static bool CheckBattleState()
        {
            var ptrParty = GameMemory.Read <IntPtr>(OffsetPtrParty, false);

            return(ptrParty != IntPtr.Zero);
        }
예제 #25
0
    public void Update()
    {
        if (!_modActive)
        {
            return;
        }

        // Read battle pointer from memory
        var battlePointer = GameMemory.Read <IntPtr>(_offsetEnemyPointer);

        // Check if we need to reset battle
        if (battlePointer == IntPtr.Zero && changedCreature != null)
        {
            changedThisBattle = false;
            changedCreature   = null;
        }

        if (battlePointer != IntPtr.Zero && !changedThisBattle)
        {
            ModLogger.WriteLine("Battle detected, modifying enemies");
            changedCreature = new bool[8];

            // Loop until all creatures are modified or limit is hit
            var loopLimit = 2000; // maximum times to attempt modification before giving up

            while (changedCreature.Contains(false) && loopLimit > 0)
            {
                loopLimit--;
                for (int i = 0; i < 8; i++)
                {
                    if (changedCreature[i])
                    {
                        continue;                     // Enemy already modified
                    }
                    var entityData   = Battle.GetEnemyEntity(i);
                    var entityName   = StringConverter.ToString(entityData.text_name);
                    int entityOffset = (int)battlePointer + _sizeBattleEntity * i;

                    if (entityData.guid == 0) // No enemy in this slot
                    {
                        continue;
                    }

                    ModLogger.WriteLine("Modifying creature: {0}", entityName);

                    var newHP = entityData.hp_max * m_HpMpMultiplier;
                    newHP = newHP > int.MaxValue ? int.MaxValue : newHP;

                    var newMP = entityData.mp_max * m_HpMpMultiplier;
                    newMP = newMP > int.MaxValue ? int.MaxValue : newMP;

                    var newStrength = entityData.strength * m_StatMultiplier;
                    newStrength = newStrength > byte.MaxValue ? byte.MaxValue : newStrength;
                    var newDefense = entityData.defense * m_StatMultiplier;
                    newDefense = newDefense > byte.MaxValue ? byte.MaxValue : newDefense;
                    var newMagic = entityData.magic * m_StatMultiplier;
                    newMagic = newMagic > byte.MaxValue ? byte.MaxValue : newMagic;
                    var newMagicDef = entityData.magic_defense * m_StatMultiplier;
                    newMagicDef = newMagicDef > byte.MaxValue ? byte.MaxValue : newMagicDef;
                    var newAgility = entityData.agility * m_StatMultiplier;
                    newAgility = newAgility > byte.MaxValue ? byte.MaxValue : newAgility;
                    var newLuck = entityData.luck * m_StatMultiplier;
                    newLuck = newLuck > byte.MaxValue ? byte.MaxValue : newLuck;
                    var newAccuracy = entityData.accuracy * m_StatMultiplier;
                    newAccuracy = newAccuracy > byte.MaxValue ? byte.MaxValue : newAccuracy;
                    var newEvasion = entityData.evasion * m_StatMultiplier;
                    newEvasion = newEvasion > byte.MaxValue ? byte.MaxValue : newEvasion;

                    // update entity values
                    GameMemory.Write <int>(entityOffset + StructHelper.GetFieldOffset <BattleEntityData>("hp_current"),
                                           newHP, false);

                    GameMemory.Write <int>(entityOffset + StructHelper.GetFieldOffset <BattleEntityData>("hp_max"),
                                           newHP, false);

                    GameMemory.Write <int>(entityOffset + StructHelper.GetFieldOffset <BattleEntityData>("hp_max2"),
                                           newHP, false);

                    GameMemory.Write <int>(entityOffset + StructHelper.GetFieldOffset <BattleEntityData>("mp_current"),
                                           newMP, false);

                    GameMemory.Write <int>(entityOffset + StructHelper.GetFieldOffset <BattleEntityData>("mp_max"),
                                           newMP, false);

                    GameMemory.Write <int>(entityOffset + StructHelper.GetFieldOffset <BattleEntityData>("mp_max2"),
                                           newMP, false);

                    GameMemory.Write <byte>(entityOffset + StructHelper.GetFieldOffset <BattleEntityData>("strength"),
                                            (byte)newStrength, false);
                    GameMemory.Write <byte>(entityOffset + StructHelper.GetFieldOffset <BattleEntityData>("defense"),
                                            (byte)newDefense, false);
                    GameMemory.Write <byte>(entityOffset + StructHelper.GetFieldOffset <BattleEntityData>("magic"),
                                            (byte)newMagic, false);
                    GameMemory.Write <byte>(entityOffset + StructHelper.GetFieldOffset <BattleEntityData>("magic_defense"),
                                            (byte)newMagicDef, false);
                    GameMemory.Write <byte>(entityOffset + StructHelper.GetFieldOffset <BattleEntityData>("agility"),
                                            (byte)newAgility, false);
                    GameMemory.Write <byte>(entityOffset + StructHelper.GetFieldOffset <BattleEntityData>("luck"),
                                            (byte)newLuck, false);
                    GameMemory.Write <byte>(entityOffset + StructHelper.GetFieldOffset <BattleEntityData>("accuracy"),
                                            (byte)newAccuracy, false);
                    GameMemory.Write <byte>(entityOffset + StructHelper.GetFieldOffset <BattleEntityData>("evasion"),
                                            (byte)newEvasion, false);


                    changedCreature[i] = true;
                }
            }
            changedThisBattle = true;
        }
    }
예제 #26
0
        private static void UpdateOffset()
        {
            var skillTablePointer = OffsetScanner.GetOffset(GameOffset.FFX_SkillTablePointer);

            _offsetSkillTable = GameMemory.Read <int>(skillTablePointer, false);
        }
예제 #27
0
 public static byte[] GetCaptureCounts()
 {
     return(GameMemory.Read <byte>(_offsetMonstersCaptured, 139, false));
 }