Mostly refactoring and cleaning up

This commit is contained in:
Knaapchen 2022-10-30 17:03:05 +01:00
parent 4a5b4790d4
commit 51743e3ba2
7 changed files with 304 additions and 114 deletions

View File

@ -13,7 +13,7 @@ namespace flyff {
struct __attribute__((packed)) InventoryItem {
union {
DEFINE_MEMBER(36, Pointer<ItemProperty>, property);
// The index (or slot) of this item in the inventory.
DEFINE_MEMBER(60, int32_t, index);
DEFINE_MEMBER(64, uint32_t, quantity);

View File

@ -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);

View File

@ -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<uint32_t>(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<unsigned>(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<unsigned>(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<unsigned>(state) << ")";
break;
}
return os;
}
};

View File

@ -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<const ObjectProperty>, 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::MoveState>((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::JumpState>((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::AttackState>((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 {

View File

@ -9,6 +9,10 @@
namespace flyff {
enum class ParamID : uint32_t {
Speed = 4,
// UnknownSpeed = 9,
// DST_HP_MAX
MaxHitPoint = 44,
// DST_HP_MAX_RATE

View File

@ -21,6 +21,8 @@ namespace flyff {
CatsReflex = 115,
Accuracy = 116,
PowerFist = 117,
Asmodeus = 0x9c,
};

View File

@ -192,7 +192,7 @@ find_skill_buff(const flyff::Pointer<flyff::Mover> &mover, const flyff::SkillID
template<size_t size>
std::vector<flyff::SkillID>
check_rebuff(const flyff::Pointer<flyff::Mover>& buffer, const flyff::Pointer<flyff::Mover> &target,
check_rebuff(const flyff::Pointer<flyff::Mover> &buffer, const flyff::Pointer<flyff::Mover> &target,
const flyff::SkillID (&buffs_to_check)[size]) {
const auto &neuz = flyff::Neuz::instance();
@ -202,7 +202,7 @@ check_rebuff(const flyff::Pointer<flyff::Mover>& buffer, const flyff::Pointer<fl
const auto &skill_property = flyff::Neuz::get_skill_property(skill_index);
const auto player_skill_level = buffer->get_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<flyff::ItemProperty*>(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<const void *>(static_cast<u32>(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<int32_t>::max();
auto food_item = flyff::Pointer<flyff::InventoryItem>(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<flyff::InventoryItem>(&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<unsigned long long*>(&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<fugg::Vector<flyff::MusicProperty>>(0x00034f7c);