From 51743e3ba252213ffc19a72239597859dbec545a Mon Sep 17 00:00:00 2001 From: Knaapchen Date: Sun, 30 Oct 2022 17:03:05 +0100 Subject: [PATCH] Mostly refactoring and cleaning up --- flyff-api/src/item/InventoryItem.h | 2 +- flyff-api/src/item/ItemProperty.h | 8 +- flyff-api/src/object/Object.h | 197 +++++++++++++++++++++++---- flyff-api/src/object/mover/Mover.h | 31 +++-- flyff-api/src/object/mover/ParamID.h | 4 + flyff-api/src/skill/SkillID.h | 2 + fugg-client/src/Client.cpp | 174 +++++++++++++---------- 7 files changed, 304 insertions(+), 114 deletions(-) diff --git a/flyff-api/src/item/InventoryItem.h b/flyff-api/src/item/InventoryItem.h index b89f2b6..9c5893b 100644 --- a/flyff-api/src/item/InventoryItem.h +++ b/flyff-api/src/item/InventoryItem.h @@ -13,7 +13,7 @@ namespace flyff { struct __attribute__((packed)) InventoryItem { union { DEFINE_MEMBER(36, Pointer, property); - + // The index (or slot) of this item in the inventory. DEFINE_MEMBER(60, int32_t, index); DEFINE_MEMBER(64, uint32_t, quantity); diff --git a/flyff-api/src/item/ItemProperty.h b/flyff-api/src/item/ItemProperty.h index 0dd6cf6..a8f94d8 100644 --- a/flyff-api/src/item/ItemProperty.h +++ b/flyff-api/src/item/ItemProperty.h @@ -20,14 +20,16 @@ namespace flyff { DEFINE_MEMBER(0, const flyff::String, model); DEFINE_MEMBER(12, const uint32_t, id); - DEFINE_MEMBER(244, const uint32_t, required_level); + DEFINE_MEMBER(60, const uint32_t, heal_hp); + + // Has to be bigger that 0 to be considered for cooldown. + DEFINE_MEMBER(112, const int32_t, cooldown_time); DEFINE_MEMBER(156, const flyff::String, name); DEFINE_MEMBER(168, const flyff::String, icon); DEFINE_MEMBER(180, const flyff::String, description); - // Has to be bigger that 0 to be considered for cooldown. - DEFINE_MEMBER(112, const int32_t, cooldown_time); + DEFINE_MEMBER(244, const uint32_t, required_level); DEFINE_MEMBER(348, const ItemKind2, item_kind2); DEFINE_MEMBER(352, const ItemKind3, item_kind3); diff --git a/flyff-api/src/object/Object.h b/flyff-api/src/object/Object.h index 238c38e..69503ed 100644 --- a/flyff-api/src/object/Object.h +++ b/flyff-api/src/object/Object.h @@ -19,38 +19,88 @@ namespace flyff { static constexpr uint32_t Turbo = 0x00000080; // Turbo mode. }; + enum class MoveState : uint8_t { + None, + // Standby + Stand, + // sit down + Sit, + // walk forward + MoveForward, + // Walk backwards + MoveBackward, + // Walk sideways (horizontal movement) + Left, + Right, + // Pick up (things, etc.) + PickUp, + // Walk horizontally left + MoveLeft, + // Walk to the right of the span + MoveRight, + // Run in place + StopRun, + }; + + enum class AttackState : uint8_t { + None, + // 1st hit attack in action + Attack1, + // Double hit attack in action + Attack2, + Attack3, + // ... + Attack4, + + Unknown1, + Unknown2, + Unknown3, + Unknown4, + + // Magic Casting #1 (Start) + Casting1, + // Magic Casting 2 times (repeat.) + Casting2, + // Magic firing action. + MagicSkill, + + // wand attack in action +// Magic, +// // Ranged attack in action +// Range, +// Range3, +// Range4, +// // Melee combat skill in action +// MeleeSkill, +// // Long range combat skill in action +// RangeSkill, +// // Special Attack: Used by monsters. +// SpecialAttack1, +// // Special Attack 2: Used by monsters. +// SpecialAttack2, + }; + + enum class JumpState : uint8_t { + None, + // Jump before jump - Jump before + Ready, + // Jumping + Jump, + // Falling + Fall, + // Landing + Land, + }; + struct State { State() = delete; static constexpr uint32_t None = 0x00000000; // Nothing. - // stop/move - - // Standby - static constexpr uint32_t Stand = 0x00000001; - // Standby EX - static constexpr uint32_t Stand2 = 0x00000002; - // sit down - static constexpr uint32_t Sit = 0x00000003; - // walk forward - static constexpr uint32_t MoveForward = 0x00000004; - // Walk backwards - static constexpr uint32_t MoveBackward = 0x00000005; - // Walk sideways (horizontal movement) - static constexpr uint32_t Left = 0x0000006; - static constexpr uint32_t Right = 0x00000007; - // Pick up (things, etc.) - static constexpr uint32_t PickUp = 0x0000008; - // Walk horizontally left - static constexpr uint32_t MoveLeft = 0x00000009; - // Walk to the right of the span - static constexpr uint32_t MoveRight = 0x0000000a; - // Run in place - static constexpr uint32_t StopRun = 0x0000000b; // All movement static constexpr uint32_t MovementAll = 0x000000FF; // Is there anything other than STAND? - static constexpr uint32_t NotStand = (MovementAll & (~Stand)); + static constexpr uint32_t NotStand = (MovementAll & (~static_cast(MoveState::Stand))); // turn left static constexpr uint32_t TurnLeft = 0x00000100; @@ -135,4 +185,103 @@ namespace flyff { }; }; + + static std::ostream &operator<<(std::ostream &os, const Object::MoveState &state) { + switch(state) { + case Object::MoveState::None: + os << "None"; + break; + case Object::MoveState::Stand: + os << "Stand"; + break; + case Object::MoveState::Sit: + os << "Sit"; + break; + case Object::MoveState::MoveForward: + os << "MoveForward"; + break; + case Object::MoveState::MoveBackward: + os << "MoveBackward"; + break; + case Object::MoveState::Left: + os << "Left"; + break; + case Object::MoveState::Right: + os << "Right"; + break; + case Object::MoveState::PickUp: + os << "PickUp"; + break; + case Object::MoveState::MoveLeft: + os << "MoveLeft"; + break; + case Object::MoveState::MoveRight: + os << "MoveRight"; + break; + case Object::MoveState::StopRun: + os << "StopRun"; + break; + default: + os << "MoveState(" << static_cast(state) << ")"; + break; + } + return os; + } + + static std::ostream &operator<<(std::ostream &os, const Object::AttackState &state) { + switch(state) { + case Object::AttackState::None: + os << "None"; + break; + case Object::AttackState::Attack1: + os << "Attack1"; + break; + case Object::AttackState::Attack2: + os << "Attack2"; + break; + case Object::AttackState::Attack3: + os << "Attack3"; + break; + case Object::AttackState::Attack4: + os << "Attack4"; + break; + case Object::AttackState::Casting1: + os << "Casting1"; + break; + case Object::AttackState::Casting2: + os << "Casting2"; + break; + case Object::AttackState::MagicSkill: + os << "MagicSkill"; + break; + default: + os << "AttackState(" << static_cast(state) << ")"; + break; + } + return os; + } + + static std::ostream &operator<<(std::ostream &os, const Object::JumpState &state) { + switch(state) { + case Object::JumpState::None: + os << "None"; + break; + case Object::JumpState::Ready: + os << "Ready"; + break; + case Object::JumpState::Jump: + os << "Jump"; + break; + case Object::JumpState::Fall: + os << "Fall"; + break; + case Object::JumpState::Land: + os << "Land"; + break; + default: + os << "JumpState(" << static_cast(state) << ")"; + break; + } + return os; + } }; \ No newline at end of file diff --git a/flyff-api/src/object/mover/Mover.h b/flyff-api/src/object/mover/Mover.h index 59a53f6..e9c8347 100644 --- a/flyff-api/src/object/mover/Mover.h +++ b/flyff-api/src/object/mover/Mover.h @@ -112,6 +112,7 @@ namespace flyff { DEFINE_MEMBER(0x18, Matrix4, world_matrix); DEFINE_MEMBER(152, const Vector3, position); + // In degrees! DEFINE_MEMBER(164, const Vector3, rotation); DEFINE_MEMBER(188, const Pointer, property); @@ -226,7 +227,7 @@ namespace flyff { return changed_parameters[id] ^ adj_param ^ id * 0x41c64e6d + 0xb5a52d1a; } - u32 get_hp() const { + uint32_t get_hp() const { return raw::w2c_f411(kMemory.to_inside(this)); } @@ -272,8 +273,9 @@ namespace flyff { return object_state; } - uint32_t get_move_state() const { - return (object_state & ObjectState::MovementAll); + Object::MoveState get_move_state() const { + // 0x000000FF + return static_cast((object_state >> 0) & 0xFF); } uint32_t get_turn_state() const { @@ -284,12 +286,14 @@ namespace flyff { return (object_state & ObjectState::LookAll); } - uint32_t get_jump_state() const { - return (object_state & ObjectState::JumpAll); + Object::JumpState get_jump_state() const { + // 0x0000F000 + return static_cast((object_state >> 12) & 0xF); } - uint32_t get_attack_state() const { - return (object_state & ObjectState::AtkAll); + Object::AttackState get_attack_state() const { + // 0x00FF0000 + return static_cast((object_state >> 16) & 0xFF); } uint32_t get_damage_state() const { @@ -330,18 +334,19 @@ namespace flyff { } bool is_moving() const { - return (get_move_state() == ObjectState::MoveForward || - get_move_state() == ObjectState::MoveBackward || - get_move_state() == ObjectState::Left || - get_move_state() == ObjectState::Right); + return (get_move_state() == Object::MoveState::MoveForward || + get_move_state() == Object::MoveState::MoveBackward || + get_move_state() == Object::MoveState::Left || + get_move_state() == Object::MoveState::Right); } bool is_jumping() const { - return (object_state & ObjectState::JumpAll) != 0; + return get_jump_state() != Object::JumpState::None && + get_jump_state() != Object::JumpState::Ready; } bool is_attacking() const { - return (object_state & ObjectState::AtkAll) != 0; + return get_attack_state() != Object::AttackState::None; } bool is_damaged() const { diff --git a/flyff-api/src/object/mover/ParamID.h b/flyff-api/src/object/mover/ParamID.h index 7ebfafc..6fb7e16 100644 --- a/flyff-api/src/object/mover/ParamID.h +++ b/flyff-api/src/object/mover/ParamID.h @@ -9,6 +9,10 @@ namespace flyff { enum class ParamID : uint32_t { + Speed = 4, +// UnknownSpeed = 9, + + // DST_HP_MAX MaxHitPoint = 44, // DST_HP_MAX_RATE diff --git a/flyff-api/src/skill/SkillID.h b/flyff-api/src/skill/SkillID.h index 522efb8..cf844cf 100644 --- a/flyff-api/src/skill/SkillID.h +++ b/flyff-api/src/skill/SkillID.h @@ -21,6 +21,8 @@ namespace flyff { CatsReflex = 115, Accuracy = 116, PowerFist = 117, + + Asmodeus = 0x9c, }; diff --git a/fugg-client/src/Client.cpp b/fugg-client/src/Client.cpp index 54be6cf..3ccc981 100644 --- a/fugg-client/src/Client.cpp +++ b/fugg-client/src/Client.cpp @@ -192,7 +192,7 @@ find_skill_buff(const flyff::Pointer &mover, const flyff::SkillID template std::vector -check_rebuff(const flyff::Pointer& buffer, const flyff::Pointer &target, +check_rebuff(const flyff::Pointer &buffer, const flyff::Pointer &target, const flyff::SkillID (&buffs_to_check)[size]) { const auto &neuz = flyff::Neuz::instance(); @@ -202,7 +202,7 @@ check_rebuff(const flyff::Pointer& buffer, const flyff::Pointerget_skill_level(skill_index); // Only check for the buff if the buffer actually has the skill. - if(player_skill_level <= 0) { + if (player_skill_level <= 0) { continue; } @@ -437,23 +437,18 @@ void on_keyup_hook(int event_type, const EmscriptenKeyboardEvent *event, void *u // current = current->next; // } while (current); - // auto items = player.inventory.begin(); - // auto length = ((uintptr_t)player.inventory.end() - (uintptr_t)player.inventory.begin()) / 0x60; + auto items = client.player->inventory.begin(); + std::cout << "Player has " << client.player->get_inventory_slots() << " slots" << std::endl; + for (auto i = 0; i < client.player->get_inventory_slots(); i++) { + if (items[i].property) { + const auto &item = items[i].property; - // std::cout << length << " items!" << std::endl; - // for(auto i = 0; i < length; i++) { - // if(items[i].id != -1) { - // // std::cout << items[i].id << std::endl; - // std::cout << "(Property address: " << static_cast(items[i].property) << ", " - // << "Item address: " << &items[i] << ") " - // << client.get_text(items[i].property->name) << ": " - // << "Cooldown=" << items[i].property->cooldown_time << ", " - // << "Maybe category=" << items[i].property->category << ", " - // << "Maybe subcategory=" << items[i].property->sub_category << ", " - // << "Is this food ? " << (items[i].property->is_food_item() ? "Yes" : "No") - // << std::endl; - // } - // } + std::cout << client.get_text(item->name) << ": " + << reinterpret_cast(static_cast(item)) << ", " + << std::endl; + + } + } } } } @@ -475,7 +470,7 @@ flyff::MoverID find_closest_target() { const auto &mover = current->mover; auto dx = std::abs(mover->position.x - neuz.player->position.x); - auto dy = std::abs(mover->position.y - neuz.player->position.y); + auto dy = std::abs(mover->position.y - neuz.player->position.y) * 5; auto dz = std::abs(mover->position.z - neuz.player->position.z); auto squared = (dx * dx) + (dy * dy) + (dz * dz); @@ -585,69 +580,87 @@ void attacker_script() { // elif attacK_target: // attack_target() - if (neuz.player->get_hp_percent() < 50) { - // neuz.show_message("Fooding because HP is under 75%");W + if (neuz.player->get_hp_percent() != 100) { + auto items = player->inventory.begin(); - std::cout << "Player has " << player->get_inventory_slots() << " slots" << std::endl; + int32_t smallest_difference = std::numeric_limits::max(); + auto food_item = flyff::Pointer(nullptr); for (auto i = 0; i < player->get_inventory_slots(); i++) { - if (items[i].property && - items[i].property->is_food() && - player->can_use_item(items[i].property)) { - std::string str = "Eating "; - str.append(neuz.get_text(items[i].property->name)); - str.append(" because HP is below 75%"); + const auto &item_property = items[i].property; + if (item_property && + player->can_use_item(item_property) && + item_property->is_food()) { + auto hp = client.player->get_hp(); + auto max_hp = client.player->get_max_hp(); + // How much HP is left over after healing with this item. + int32_t difference = max_hp - (hp + item_property->heal_hp); - neuz.show_message(str); - - client.send_use_item_in_inventory(i); - - break; + if (difference >= 0 && std::abs(difference) < std::abs(smallest_difference)) { + food_item = flyff::Pointer(&items[i]); + smallest_difference = difference; + } } } + + if (food_item) { + std::string str = "Eating "; + str.append(neuz.get_text(food_item->property->name)); + str.append(" because it has the smallest difference of "); + str.append(std::to_string(smallest_difference)); + + neuz.show_message(str); + + client.send_use_item_in_inventory(food_item->index); + } } - if (neuz.player->get_move_state() == 1 && + if (neuz.player->get_move_state() == flyff::Object::MoveState::Stand && !neuz.player->is_attacking()) { // Check buffs. static constexpr flyff::SkillID buffs_to_check[] = { - flyff::SkillID::HeapUp, - flyff::SkillID::Haste, - flyff::SkillID::Patience, - flyff::SkillID::BeefUp, +// flyff::SkillID::MentalSign, +// flyff::SkillID::HeapUp, +// flyff::SkillID::QuickStep, +// flyff::SkillID::Patience, +// flyff::SkillID::Haste, +// flyff::SkillID::BeefUp, +// flyff::SkillID::Accuracy, +// flyff::SkillID::CatsReflex, +// flyff::SkillID::CannonBall, }; auto item = neuz.get_mover(current_pickup_item); auto monster = neuz.get_mover(current_target); - if (neuz.player->get_job() == flyff::JobID::Assist) { + if (neuz.player->get_job() == flyff::JobID::Assist || neuz.player->get_job() == flyff::JobID::Billposter) { const auto &main_hand = player->get_equipped_item(flyff::Part::MainHand); const auto &off_hand = player->get_equipped_item(flyff::Part::Shield); - auto buffs = check_rebuff(neuz.player, neuz.player, buffs_to_check); - if (!buffs.empty() && (!item || item->is_despawned) && (!monster || monster->is_dead())) { - const auto skill_index = buffs.back(); - if (!main_hand || main_hand->item_kind3 != flyff::ItemKind3::CheerStick) { - const auto &stick = find_first_equippable_item(flyff::ItemKind3::CheerStick); - - if (stick) { - buffs.pop_back(); - - client.send_use_item_in_inventory(stick->index); - client.send_use_skill(skill_index); - return; - } else { - neuz.show_message("Unable to find a stick", {0xFF, 0, 0}); - } - } else { - buffs.pop_back(); - client.send_use_skill(skill_index); - return; - } - } - - if (buffs.empty()) { +// auto buffs = check_rebuff(neuz.player, neuz.player, buffs_to_check); +// if (!buffs.empty() && (!item || item->is_despawned) && (!monster || monster->is_dead())) { +// const auto skill_index = buffs.back(); +// if (!main_hand || main_hand->item_kind3 != flyff::ItemKind3::CheerStick) { +// const auto &stick = find_first_equippable_item(flyff::ItemKind3::CheerStick); +// +// if (stick) { +// buffs.pop_back(); +// +// client.send_use_item_in_inventory(stick->index); +// client.send_use_skill(skill_index); +// return; +// } else { +// neuz.show_message("Unable to find a stick", {0xFF, 0, 0}); +// } +// } else { +// buffs.pop_back(); +// client.send_use_skill(skill_index); +// return; +// } +// } +// +// if (buffs.empty()) { if (!main_hand || main_hand->item_kind3 != flyff::ItemKind3::KnuckleHammer) { const auto &knuckle = find_first_equippable_item(flyff::ItemKind3::KnuckleHammer); @@ -667,7 +680,12 @@ void attacker_script() { neuz.show_message("Unable to find a shield", {0xFF, 0, 0}); } } - } + + if(!check_rebuff(neuz.player, neuz.player, { flyff::SkillID::Asmodeus }).empty()) { + client.send_use_skill(flyff::SkillID::Asmodeus); + return; + } +// } } if (item && !item->is_despawned && neuz.player->move_toward_target == 0) { @@ -744,7 +762,7 @@ void healer_script() { return; } - if (client.player->get_move_state() == 1 && + if (client.player->get_move_state() == flyff::Object::MoveState::Stand && !client.player->is_attacking()) { if (client.player->selected_target != current_heal_target) { @@ -771,7 +789,7 @@ void healer_script() { return; } // If I'm hit, heal myself. - if(client.player->get_hp_percent() < 75) { + if (client.player->get_hp_percent() < 75) { client.send_clear_target(); client.player->selected_target = 0; @@ -783,14 +801,14 @@ void healer_script() { // For target, check all buffs. static constexpr flyff::SkillID buffs_to_check[] = { flyff::SkillID::MentalSign, - flyff::SkillID::Patience, - flyff::SkillID::QuickStep, flyff::SkillID::HeapUp, + flyff::SkillID::QuickStep, + flyff::SkillID::Patience, flyff::SkillID::Haste, flyff::SkillID::BeefUp, flyff::SkillID::Accuracy, flyff::SkillID::CatsReflex, - flyff::SkillID::CannonBall + flyff::SkillID::CannonBall, }; auto buffs = check_rebuff(client.player, target, buffs_to_check); @@ -798,7 +816,7 @@ void healer_script() { auto skill_index = buffs.back(); buffs.pop_back(); - const auto& skill = fugg::Client::get_skill_property(skill_index); + const auto &skill = fugg::Client::get_skill_property(skill_index); std::string str = "Buffing target with"; str.append(client.get_text(skill->name)); client.show_message(str); @@ -808,7 +826,7 @@ void healer_script() { } } // Check for rebuff on yourself - if(!target->is_in_combat(1500)){ + if (!target->is_in_combat(1500)) { // For FS itself, only these selected buffs. static constexpr flyff::SkillID buffs_to_check[] = { flyff::SkillID::MentalSign, @@ -838,6 +856,19 @@ void healer_script() { } void before_main_loop() { +} + +void after_main_loop() { + const auto &client = fugg::Client::instance(); + + if (client.player && client.player->is_moving() && !client.player->is_jumping()) { +// std::cout << "Sending jump packet!" << std::endl; +// +// double rotation_y = client.player->rotation.y; +// client.send_motion_packet(0x2, *reinterpret_cast(&rotation_y)); + } + + switch (script) { case ScriptType::Attacker: attacker_script(); @@ -854,9 +885,6 @@ void before_main_loop() { break; } -} - -void after_main_loop() { // std::string test; // auto& music_properties = fugg::module_ref>(0x00034f7c);