Some refactors after installing CLion
This commit is contained in:
parent
9af9d664f5
commit
97169c715f
|
|
@ -2,6 +2,7 @@ add_library (
|
|||
flyff-api
|
||||
"src/flyff.cpp"
|
||||
"src/Neuz.cpp"
|
||||
"src/Mover.cpp"
|
||||
"src/import.cpp"
|
||||
"src/api.cpp"
|
||||
"include/flyff.h"
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
// #include "../src/api.h"
|
||||
#include "../src/Neuz.h"
|
||||
#include "../src/Mover.h"
|
||||
#include "../src/skill.h"
|
||||
|
||||
#include "../src/import.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ struct __attribute__((packed)) Mover {
|
|||
|
||||
using Parameter = unsigned long;
|
||||
|
||||
static constexpr Parameter DST_HP_MAX = 0x2c;
|
||||
static constexpr Parameter DST_HP_MAX_RATE = 0x35;
|
||||
|
||||
using ObjectStateFlags = Object::StateFlags;
|
||||
using ObjectState = Object::State;
|
||||
|
||||
|
|
@ -36,6 +39,8 @@ struct __attribute__((packed)) Mover {
|
|||
DEFINE_MEMBER(52, u32, get_level);
|
||||
DEFINE_MEMBER(56, u32, get_gender);
|
||||
|
||||
DEFINE_MEMBER(96, u32, get_active_hand_item_prop);
|
||||
|
||||
DEFINE_MEMBER(144, u32, get_max_origin_hp);
|
||||
DEFINE_MEMBER(148, u32, get_max_origin_mp);
|
||||
|
||||
|
|
@ -43,6 +48,55 @@ struct __attribute__((packed)) Mover {
|
|||
};
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) Skill {
|
||||
union {
|
||||
DEFINE_MEMBER(0, uintptr_t, index);
|
||||
DEFINE_MEMBER(4, uintptr_t, level);
|
||||
};
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) Buff {
|
||||
static constexpr Parameter BUFF_ITEM = 0;
|
||||
static constexpr Parameter BUFF_SKILL = 1;
|
||||
|
||||
struct __attribute__((packed)) Vtable {
|
||||
union {
|
||||
DEFINE_MEMBER(28, uintptr_t, get_type);
|
||||
DEFINE_MEMBER(32, uintptr_t, get_id);
|
||||
};
|
||||
};
|
||||
|
||||
union {
|
||||
DEFINE_MEMBER(0, Pointer<Vtable>, vtable);
|
||||
|
||||
DEFINE_MEMBER(4, Pointer<ObjectProperty>, property);
|
||||
DEFINE_MEMBER(8, Parameter, param_id);
|
||||
|
||||
DEFINE_MEMBER(16, uint64_t, time_instantiated);
|
||||
DEFINE_MEMBER(24, uint64_t, time_total);
|
||||
|
||||
DEFINE_MEMBER(32, int, level);
|
||||
|
||||
DEFINE_MEMBER(36, bool, is_removed);
|
||||
DEFINE_MEMBER(37, bool, is_sfx);
|
||||
};
|
||||
|
||||
int get_type() const {
|
||||
using Fn = FunctionPointer<u32, u32>;
|
||||
const auto &fn = fugg::function_ref<Fn>(vtable->get_type);
|
||||
|
||||
return fn(kMemory.to_inside(this));
|
||||
}
|
||||
|
||||
int get_id() const {
|
||||
using Fn = FunctionPointer<u32, u32>;
|
||||
const auto &fn = fugg::function_ref<Fn>(vtable->get_id);
|
||||
|
||||
return fn(kMemory.to_inside(this));
|
||||
}
|
||||
|
||||
uint64_t get_time_remaining() const;
|
||||
};
|
||||
|
||||
union {
|
||||
DEFINE_MEMBER(0x0, const Pointer<Vtable>, vtable);
|
||||
|
|
@ -54,11 +108,14 @@ struct __attribute__((packed)) Mover {
|
|||
|
||||
DEFINE_MEMBER(188, Pointer<ObjectProperty>, property);
|
||||
|
||||
DEFINE_MEMBER(212, int, property_id);
|
||||
DEFINE_MEMBER(216, bool, is_despawned);
|
||||
DEFINE_MEMBER(352, MoverID, object_id);
|
||||
|
||||
DEFINE_MEMBER(920, Parameter, adjustParam[MAX_PARAM]);
|
||||
DEFINE_MEMBER(1248, Parameter, changeParam[MAX_PARAM]);
|
||||
DEFINE_MEMBER(920, Parameter, adjusted_parameters[MAX_PARAM]);
|
||||
DEFINE_MEMBER(1248, Parameter, changed_parameters[MAX_PARAM]);
|
||||
|
||||
DEFINE_MEMBER(1576, Vector<Pointer<Buff>>, buffs);
|
||||
|
||||
DEFINE_MEMBER(2020, const String, name);
|
||||
|
||||
|
|
@ -80,6 +137,8 @@ struct __attribute__((packed)) Mover {
|
|||
|
||||
DEFINE_MEMBER(1840, int, hitpoints);
|
||||
|
||||
DEFINE_MEMBER(1848, int, is_grounded);
|
||||
|
||||
DEFINE_MEMBER(1792, int, current_animation);
|
||||
|
||||
DEFINE_MEMBER(204, ObjectType, type);
|
||||
|
|
@ -93,9 +152,6 @@ struct __attribute__((packed)) Mover {
|
|||
|
||||
DEFINE_MEMBER(192, uintptr_t, world);
|
||||
|
||||
// Only works on players.
|
||||
DEFINE_MEMBER(2472, uint32_t, level);
|
||||
|
||||
DEFINE_MEMBER(860, Vector<InventoryItem>, inventory);
|
||||
|
||||
|
||||
|
|
@ -103,18 +159,25 @@ struct __attribute__((packed)) Mover {
|
|||
DEFINE_MEMBER(3348, uint64_t, last_refresher_time);
|
||||
DEFINE_MEMBER(3356, uint64_t, last_vitaldrink_time);
|
||||
|
||||
const MinimumSize<4096> __size;
|
||||
DEFINE_MEMBER(3424, Vector<Skill>, skills);
|
||||
|
||||
const MinimumSize<4096> size;
|
||||
};
|
||||
|
||||
uint32_t get_skill_level(uint32_t skill_index) const {
|
||||
for (const auto &skill: skills) {
|
||||
if (skill_index == skill.index)
|
||||
return skill.level;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool can_use_item(const Pointer<ItemProperty> &property) {
|
||||
return raw::w2c_f2466(kMemory.to_inside(&last_food_time), static_cast<u32>(property));
|
||||
}
|
||||
|
||||
bool is_in_combat() const {
|
||||
const unsigned long long& now = fugg::module_ref<unsigned long long>(0x00032880);
|
||||
// 10 seconds
|
||||
return now - last_combat < 10000000;
|
||||
}
|
||||
bool is_in_combat() const;
|
||||
|
||||
Parameter get_param(uint32_t index, Parameter base) const {
|
||||
Parameter changeParam = get_change_param(index);
|
||||
|
|
@ -130,39 +193,44 @@ struct __attribute__((packed)) Mover {
|
|||
|
||||
Parameter get_adjust_param(Parameter index) const {
|
||||
// Find these values in CMover::Init
|
||||
return adjustParam[index] ^ adj_param ^ 0x0554e725 + index * 0x41c64e6d;
|
||||
return adjusted_parameters[index] ^ adj_param ^ 0x0554e725 + index * 0x41c64e6d;
|
||||
}
|
||||
|
||||
Parameter get_change_param(Parameter index) const {
|
||||
return changeParam[index] ^ adj_param ^ index * 0x41c64e6d + 0xb5a52d1a;
|
||||
return changed_parameters[index] ^ adj_param ^ index * 0x41c64e6d + 0xb5a52d1a;
|
||||
}
|
||||
|
||||
u32 get_hp() const {
|
||||
return raw::w2c_f411(kMemory.to_inside(this));
|
||||
}
|
||||
|
||||
u32 get_max_hp() const {
|
||||
static constexpr Parameter DST_HP_MAX = 0x2c;
|
||||
static constexpr Parameter DST_HP_MAX_RATE = 0x35;
|
||||
flyff::Pointer<flyff::ItemProperty> get_equipped_item(const flyff::Part &part) {
|
||||
using Fn = FunctionPointer<u32, u32, u32>;
|
||||
const auto &fn = fugg::function_ref<Fn>(vtable->get_active_hand_item_prop);
|
||||
|
||||
const auto &ptr = fn(kMemory.to_inside(this), static_cast<uint32_t>(part));
|
||||
return flyff::Pointer<flyff::ItemProperty>(ptr);
|
||||
}
|
||||
|
||||
uint32_t get_max_hp() const {
|
||||
float factor = 1.0f;
|
||||
int result = get_param(DST_HP_MAX, get_max_origin_hp());
|
||||
int percent = get_param(DST_HP_MAX_RATE, 0);
|
||||
|
||||
factor += (float) percent / (float) 100;
|
||||
result = (int)(result * factor);
|
||||
result = static_cast<float>(result) * factor;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
u32 get_hp_percent(int percent = 100) const {
|
||||
uint32_t get_hp_percent(int percent = 100) const {
|
||||
int max = get_max_hp();
|
||||
if (max == 0) return 0;
|
||||
|
||||
return get_hp() * percent / max;
|
||||
}
|
||||
|
||||
u32 get_max_origin_hp() const {
|
||||
uint32_t get_max_origin_hp() const {
|
||||
using Fn = FunctionPointer<u32, u32, u32, u32>;
|
||||
const auto &fn = fugg::function_ref<Fn>(vtable->get_max_origin_hp);
|
||||
|
||||
|
|
@ -217,16 +285,19 @@ struct __attribute__((packed)) Mover {
|
|||
bool is_sit() const {
|
||||
return (object_state_flags & ObjectStateFlags::Sit) != 0;
|
||||
}
|
||||
|
||||
// Whether the movement state is running, not if the Mover
|
||||
// is actually moving. See `is_moving()`
|
||||
bool is_run() const {
|
||||
return (object_state_flags & ObjectStateFlags::Walk) == 0;
|
||||
}
|
||||
|
||||
// Whether the movement state is walking, not if the Mover
|
||||
// is actually moving. See `is_moving()`
|
||||
bool is_walk() const {
|
||||
return (object_state_flags & ObjectStateFlags::Walk) != 0;
|
||||
}
|
||||
|
||||
// Normal action - No other commands have any effect during this action.
|
||||
bool is_action() const {
|
||||
return (object_state & ObjectState::ActionAll) != 0;
|
||||
|
|
|
|||
|
|
@ -6,17 +6,20 @@
|
|||
// static_assert(offsetof(TestMover, name) == 0x7f4, "Mover.name needs to be at
|
||||
// 2020");
|
||||
|
||||
|
||||
namespace flyff {
|
||||
namespace raw {
|
||||
static const uintptr_t& WORLD = 0x00035eb8;
|
||||
static const uintptr_t& PLAYER = WORLD + 4;
|
||||
static constexpr uintptr_t WORLD = 0x00035eb8;
|
||||
static constexpr uintptr_t PLAYER = WORLD + 4;
|
||||
|
||||
static const uintptr_t& PLAYER_OBJECT_ID = 0x00034ef8;
|
||||
static constexpr uintptr_t PLAYER_OBJECT_ID = 0x00034ef8;
|
||||
// The messages that are limited to 5 that are show temporarily.
|
||||
static const uintptr_t& MESSAGES_UI = 0x00035ec8;
|
||||
static const uintptr_t& ANNOUNCEMENTS_UI = 0x00034c94;
|
||||
static const uintptr_t& MOVER_MAP = 0x000332c8;
|
||||
static constexpr uintptr_t MESSAGES_UI = 0x00035ec8;
|
||||
static constexpr uintptr_t ANNOUNCEMENTS_UI = 0x00034c94;
|
||||
static constexpr uintptr_t MOVER_MAP = 0x000332c8;
|
||||
|
||||
static constexpr uintptr_t CURRENT_TIME = 0x00032880;
|
||||
static constexpr uintptr_t START_TIME = 0x000328c0;
|
||||
static constexpr uintptr_t MAYBE_LOGIN_TIME = START_TIME + 8;
|
||||
|
||||
extern "C" {
|
||||
// get_mover
|
||||
|
|
@ -29,6 +32,8 @@ extern void w2c_f341(u32, u32, u32);
|
|||
extern void w2c_f607(u32, u32, u32);
|
||||
// can_attack_target
|
||||
extern u32 w2c_f515(u32, u32);
|
||||
// CProject::GetSkillProp()
|
||||
extern u32 w2c_f440(u32, u32);
|
||||
};
|
||||
|
||||
static const auto& get_mover = w2c_f208;
|
||||
|
|
@ -36,6 +41,7 @@ static const auto& get_text = w2c_f167;
|
|||
static const auto& show_message = w2c_f341;
|
||||
static const auto& show_announcement = w2c_f607;
|
||||
static const auto& can_attack_target = w2c_f515;
|
||||
static const auto& get_skill_prop = w2c_f440;
|
||||
}; // namespace raw
|
||||
|
||||
// Emscripten runtime:
|
||||
|
|
@ -50,7 +56,10 @@ Neuz::Neuz()
|
|||
player(make_ref<Pointer<Mover>>(raw::PLAYER)),
|
||||
messages_ui(make_ref<Pointer<uintptr_t>>(raw::MESSAGES_UI)),
|
||||
announcements_ui(make_ref<Pointer<uintptr_t>>(raw::ANNOUNCEMENTS_UI)),
|
||||
player_object_id(make_ref<MoverID>(raw::PLAYER_OBJECT_ID)) {}
|
||||
player_object_id(make_ref<MoverID>(raw::PLAYER_OBJECT_ID)),
|
||||
current_time(make_ref<uint64_t>(raw::CURRENT_TIME)),
|
||||
start_time(make_ref<uint64_t>(raw::START_TIME)),
|
||||
maybe_login_time(make_ref<uint64_t>(raw::MAYBE_LOGIN_TIME)) {}
|
||||
|
||||
Neuz& Neuz::instance() {
|
||||
static bool initialised = false;
|
||||
|
|
@ -126,9 +135,14 @@ void Neuz::show_announcement(const std::string& message,
|
|||
|
||||
bool Neuz::is_valid_attack(const Pointer<Mover>& attacker,
|
||||
const Pointer<Mover>& defender) const {
|
||||
auto result =
|
||||
raw::can_attack_target(static_cast<u32>(attacker), static_cast<u32>(defender));
|
||||
auto result = raw::can_attack_target(static_cast<u32>(attacker),
|
||||
static_cast<u32>(defender));
|
||||
|
||||
return result != 0;
|
||||
}
|
||||
|
||||
|
||||
Pointer<SkillProperty> Neuz::get_skill_property(int id) const {
|
||||
return Pointer<SkillProperty>(raw::get_skill_prop(id, 1));
|
||||
}
|
||||
} // namespace flyff
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <cstdint>
|
||||
|
||||
#include "skill.h"
|
||||
#include "Mover.h"
|
||||
|
||||
namespace flyff {
|
||||
|
|
@ -38,6 +39,10 @@ class Neuz {
|
|||
const Pointer<Mover>& player;
|
||||
const MoverID& player_object_id;
|
||||
|
||||
const uint64_t& current_time;
|
||||
const uint64_t& start_time;
|
||||
const uint64_t& maybe_login_time;
|
||||
|
||||
// Execute the `main` function of the flyff-client.
|
||||
int main() const;
|
||||
|
||||
|
|
@ -53,6 +58,8 @@ class Neuz {
|
|||
|
||||
bool is_valid_attack(const Pointer<Mover>& attacker, const Pointer<Mover>& defender) const;
|
||||
|
||||
Pointer<SkillProperty> get_skill_property(int id) const;
|
||||
|
||||
// Easy to implement: Just send a EmscriptenKeyboardEvent* to the registered
|
||||
// function. void send_keydown(); void send_keyup(); void send_keypress();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -36,11 +36,11 @@ class Memory {
|
|||
return reinterpret_cast<uintptr_t>((*memory)->data);
|
||||
}
|
||||
|
||||
uintptr_t to_inside(const uintptr_t offset) {
|
||||
uintptr_t to_inside(const uintptr_t offset) const {
|
||||
return offset != NULL ? offset - start() : NULL;
|
||||
}
|
||||
|
||||
intptr_t to_inside(const void* offset) {
|
||||
uintptr_t to_inside(const void *offset) const {
|
||||
return to_inside(reinterpret_cast<uintptr_t>(offset));
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +57,8 @@ class Memory {
|
|||
|
||||
static auto kMemory = Memory(&Z_clientZ_memory);
|
||||
|
||||
class Table {};
|
||||
class Table {
|
||||
};
|
||||
|
||||
static const auto &kTable = &Z_clientZ_table;
|
||||
|
||||
|
|
@ -67,6 +68,9 @@ T& make_ref(uintptr_t address) {
|
|||
return *reinterpret_cast<T *>(kMemory.to_outside(address));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class __attribute__((packed)) Pointer;
|
||||
|
||||
template<typename T>
|
||||
class __attribute__((packed)) Pointer {
|
||||
// Always located INSIDE the flyff module.
|
||||
|
|
@ -79,10 +83,13 @@ class __attribute__((packed)) Pointer {
|
|||
Pointer() : offset(0) {}
|
||||
|
||||
public:
|
||||
explicit Pointer(void* ptr) : offset(ptr == nullptr ? 0 : kMemory.to_inside(reinterpret_cast<uintptr_t>(ptr))) { }
|
||||
explicit Pointer(void const *ptr) : offset(
|
||||
ptr == nullptr ? 0 : kMemory.to_inside(reinterpret_cast<uintptr_t>(ptr))) {}
|
||||
|
||||
explicit Pointer(uintptr_t ptr) : offset(ptr) {}
|
||||
|
||||
Pointer(const Pointer<T> &other) : offset(other.offset) {}
|
||||
|
||||
Pointer<T> &operator=(Pointer<T> other) {
|
||||
offset = other.offset;
|
||||
return *this;
|
||||
|
|
@ -92,10 +99,6 @@ class __attribute__((packed)) Pointer {
|
|||
return as_outside();
|
||||
}
|
||||
|
||||
T& operator*() const {
|
||||
return *as_outside();
|
||||
}
|
||||
|
||||
explicit operator T *() const {
|
||||
return as_outside();
|
||||
}
|
||||
|
|
@ -105,7 +108,7 @@ class __attribute__((packed)) Pointer {
|
|||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
return offset != 0 ? as_outside() != nullptr : false;
|
||||
return offset != 0 && as_outside() != nullptr;
|
||||
}
|
||||
|
||||
bool operator==(Pointer<T> const &rhs) const { return offset == rhs.offset; }
|
||||
|
|
|
|||
|
|
@ -1,26 +1,97 @@
|
|||
#pragma once
|
||||
|
||||
#include "core.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace flyff {
|
||||
struct __attribute__((packed)) ItemProperty {
|
||||
static constexpr uint32_t IK2_FOOD = 14;
|
||||
static constexpr uint32_t IK3_QUEST = 43;
|
||||
#include "core.h"
|
||||
|
||||
namespace flyff {
|
||||
|
||||
enum class Part : uint32_t {
|
||||
// Excluded from equipment
|
||||
Head = 0,
|
||||
// Excluded from equipment
|
||||
Hair = 1,
|
||||
UpperBody = 2,
|
||||
LowerBody = 3,
|
||||
Hand = 4,
|
||||
Foot = 5,
|
||||
Helmet = 6,
|
||||
Robe = 7,
|
||||
Cloak = 8,
|
||||
OffHand = 9,
|
||||
MainHand = 10,
|
||||
Shield = 11,
|
||||
Mask = 12,
|
||||
// Exclude from equipment - This is to go after #16, but it has to
|
||||
// be converted, so I solved it this way.
|
||||
RIDE = 13,
|
||||
// Simultaneous output parts up to here
|
||||
// If you want to increase the number above 16, you must tell xuzhu.
|
||||
// Otherwise, it's an error.
|
||||
|
||||
CAP2 = 14, // Exclude from equipment
|
||||
UPPER2 = 15, // Exclude from equipment
|
||||
|
||||
// For parts that are not rendered on the actual screen, use 16 or more.
|
||||
// earrings, rings, etc.
|
||||
|
||||
LOWER2 = 16,
|
||||
HAND2 = 17,
|
||||
FOOT2 = 18,
|
||||
// Installed up to here, but by installing this, other parts are invisible.
|
||||
// (It's different from Exclusive.)
|
||||
|
||||
// Necklace
|
||||
NECKLACE1 = 19,
|
||||
// Ring
|
||||
RING1 = 20,
|
||||
RING2 = 21,
|
||||
// Earrings
|
||||
EARRING1 = 22,
|
||||
EARRING2 = 23,
|
||||
// A space to wear props except necklaces, rings, and earrings
|
||||
PROPERTY = 24,
|
||||
// various bullet slots
|
||||
BULLET = 25,
|
||||
// Fashion item hat
|
||||
HAT = 26,
|
||||
// Fashion Outfits
|
||||
CLOTH = 27,
|
||||
// Fashion Gloves
|
||||
GLOVE = 28,
|
||||
// Fashion Boots
|
||||
BOOTS = 29,
|
||||
// Fashion Cloak
|
||||
CLOAK2 = 30,
|
||||
};
|
||||
|
||||
enum class ItemKind2 : uint32_t {
|
||||
Food = 14,
|
||||
Quest = 25,
|
||||
};
|
||||
|
||||
enum class ItemKind3 : uint32_t {
|
||||
CheerStick = 202,
|
||||
KnuckleHammer = 203,
|
||||
|
||||
Shield = 300,
|
||||
};
|
||||
|
||||
|
||||
struct __attribute__((packed)) ItemProperty {
|
||||
static constexpr uint32_t COOLDOWN_FOOD = 0x00;
|
||||
static constexpr uint32_t COOLDOWN_REFRESHER = 0x03;
|
||||
static constexpr uint32_t COOLDOWN_VITALDRINK = 0x04;
|
||||
|
||||
static constexpr uint32_t RECOVERY_COOLDOWN_INDEX[] = {
|
||||
0x03, 0x04, 0x00, 0x00, 0x01
|
||||
};
|
||||
static constexpr uint32_t RECOVERY_COOLDOWN_INDEX[] = {0x03, 0x04, 0x00,
|
||||
0x00, 0x01};
|
||||
|
||||
union {
|
||||
DEFINE_MEMBER(0, const flyff::String, model);
|
||||
DEFINE_MEMBER(12, const uint32_t, id);
|
||||
|
||||
DEFINE_MEMBER(244, const uint32_t, required_level);
|
||||
|
||||
DEFINE_MEMBER(156, const flyff::String, name);
|
||||
DEFINE_MEMBER(168, const flyff::String, icon);
|
||||
DEFINE_MEMBER(180, const flyff::String, description);
|
||||
|
|
@ -28,17 +99,17 @@ struct __attribute__((packed)) ItemProperty {
|
|||
// Has to be bigger that 0 to be considered for cooldown.
|
||||
DEFINE_MEMBER(112, const int32_t, cooldown_time);
|
||||
|
||||
DEFINE_MEMBER(348, const uint32_t, item_kind2);
|
||||
DEFINE_MEMBER(352, const uint32_t, item_kind3);
|
||||
DEFINE_MEMBER(348, const ItemKind2, item_kind2);
|
||||
DEFINE_MEMBER(352, const ItemKind3, item_kind3);
|
||||
|
||||
const MinimumSize<456> __size;
|
||||
const MinimumSize<456> size;
|
||||
};
|
||||
|
||||
bool is_food() {
|
||||
bool is_food() const {
|
||||
static const uint32_t RECOVERY_SUB_CATEGORY_START = 1400;
|
||||
|
||||
if(item_kind2 == IK2_FOOD) {
|
||||
const uint32_t cd = item_kind3 - RECOVERY_SUB_CATEGORY_START;
|
||||
if (item_kind2 == ItemKind2::Food) {
|
||||
const uint32_t cd = static_cast<uint32_t>(item_kind3) - RECOVERY_SUB_CATEGORY_START;
|
||||
if (cd < 5) {
|
||||
return RECOVERY_COOLDOWN_INDEX[cd] == COOLDOWN_FOOD;
|
||||
}
|
||||
|
|
@ -47,9 +118,7 @@ struct __attribute__((packed)) ItemProperty {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool is_quest() {
|
||||
return item_kind3 == IK3_QUEST;
|
||||
}
|
||||
bool is_quest() const { return item_kind2 == ItemKind2::Quest; }
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) InventoryItem {
|
||||
|
|
@ -59,7 +128,7 @@ struct __attribute__((packed)) InventoryItem {
|
|||
DEFINE_MEMBER(60, int32_t, index);
|
||||
DEFINE_MEMBER(64, uint32_t, quantity);
|
||||
|
||||
const MinimumSize<96> __size;
|
||||
const MinimumSize<96> size;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -681,7 +681,7 @@ static void w2c_f436(u32, u32, u32);
|
|||
static u32 w2c_f437(u32);
|
||||
static void w2c_f438(u32);
|
||||
static void w2c_f439(u32, u32);
|
||||
static u32 w2c_f440(u32, u32);
|
||||
u32 w2c_f440(u32, u32);
|
||||
static void w2c_f441(u32, u64, u64, u64, u64);
|
||||
static void w2c_f442(u32, u32, u32, u32);
|
||||
static u32 w2c_f443(u32, u32, u32, u32, u32);
|
||||
|
|
@ -122491,7 +122491,7 @@ static void w2c_f439(u32 w2c_p0, u32 w2c_p1) {
|
|||
FUNC_EPILOGUE;
|
||||
}
|
||||
|
||||
static u32 w2c_f440(u32 w2c_p0, u32 w2c_p1) {
|
||||
u32 w2c_f440(u32 w2c_p0, u32 w2c_p1) {
|
||||
u32 w2c_l2 = 0, w2c_l3 = 0, w2c_l4 = 0, w2c_l5 = 0, w2c_l6 = 0, w2c_l7 = 0, w2c_l8 = 0;
|
||||
FUNC_PROLOGUE;
|
||||
u32 w2c_i0, w2c_i1, w2c_i2, w2c_i3;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ add_executable(
|
|||
"src/export/embind.cpp"
|
||||
"src/export/env.cpp"
|
||||
"src/export/platform.cpp"
|
||||
)
|
||||
src/Bot.cpp src/Bot.h src/Action.h)
|
||||
|
||||
# Flyff is based on c++14
|
||||
add_definitions(-std=c++14 -Os)
|
||||
|
|
|
|||
|
|
@ -5,8 +5,7 @@
|
|||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace fugg
|
||||
{
|
||||
namespace fugg {
|
||||
}
|
||||
|
||||
constexpr const uint32_t hash_to_id(const uint32_t hashed) {
|
||||
|
|
@ -93,14 +92,17 @@ void use_item_in_inventory(const uint32_t& slot) {
|
|||
send_packet(0x410, packet);
|
||||
}
|
||||
|
||||
using MotionParam = unsigned long long;
|
||||
struct MotionPacketParams {
|
||||
unsigned long long param0 = 0;
|
||||
unsigned long long param1 = 0;
|
||||
unsigned long long param2 = 0;
|
||||
unsigned long long param3 = 0;
|
||||
};
|
||||
|
||||
void send_motion_packet(
|
||||
const uint32_t &action,
|
||||
MotionParam param0 = 0,
|
||||
MotionParam param1 = 0,
|
||||
MotionParam param2 = 0,
|
||||
MotionParam param3 = 0
|
||||
MotionPacketParams params,
|
||||
uint32_t server_tick_delta = 0
|
||||
) {
|
||||
const int32_t motion_packet_id = 0x404;
|
||||
const auto &neuz = flyff::Neuz::instance();
|
||||
|
|
@ -110,34 +112,40 @@ void send_motion_packet(
|
|||
std::vector<uint8_t> packet;
|
||||
|
||||
uint8_t param_flags = 0;
|
||||
if(param0 != 0) param_flags |= 1;
|
||||
if(param1 != 0) param_flags |= 2;
|
||||
if(param2 != 0) param_flags |= 4;
|
||||
if(param3 != 0) param_flags |= 8;
|
||||
if (params.param0 != 0) param_flags |= 1;
|
||||
if (params.param1 != 0) param_flags |= 2;
|
||||
if (params.param2 != 0) param_flags |= 4;
|
||||
if (params.param3 != 0) param_flags |= 8;
|
||||
|
||||
packet_push<flyff::Vector3>(packet, neuz.player->position);
|
||||
packet_push<uint8_t>(packet, action);
|
||||
packet_push<uint8_t>(packet, param_flags);
|
||||
packet_push(packet, neuz.player->server_tick);
|
||||
packet_push(packet, neuz.player->server_tick + server_tick_delta);
|
||||
|
||||
if(param0 != 0) packet_push<unsigned long long>(packet, param0);
|
||||
if(param1 != 0) packet_push<unsigned long long>(packet, param1);
|
||||
if(param2 != 0) packet_push<unsigned long long>(packet, param2);
|
||||
if(param3 != 0) packet_push<unsigned long long>(packet, param3);
|
||||
if (params.param0 != 0) packet_push<unsigned long long>(packet, params.param0);
|
||||
if (params.param1 != 0) packet_push<unsigned long long>(packet, params.param1);
|
||||
if (params.param2 != 0) packet_push<unsigned long long>(packet, params.param2);
|
||||
if (params.param3 != 0) packet_push<unsigned long long>(packet, params.param3);
|
||||
|
||||
send_packet(motion_packet_id, packet);
|
||||
}
|
||||
|
||||
void set_target(const unsigned long long &id) {
|
||||
send_motion_packet(0x04, id);
|
||||
send_motion_packet(0x04, {id});
|
||||
}
|
||||
|
||||
void clear_target() {
|
||||
send_motion_packet(0x04);
|
||||
send_motion_packet(0x04, {});
|
||||
}
|
||||
|
||||
void interact_target(const unsigned long long &index) {
|
||||
send_motion_packet(0x11, index);
|
||||
send_motion_packet(0x11, {index});
|
||||
}
|
||||
|
||||
void use_skill(unsigned long long id, uint32_t server_tick_delta = 0) {
|
||||
static constexpr unsigned long long param1 = -1;
|
||||
|
||||
send_motion_packet(0x5, {id, param1}, server_tick_delta);
|
||||
}
|
||||
|
||||
// void move_to(const float& x, const float& y, const float& z) {
|
||||
|
|
@ -169,16 +177,187 @@ void write_chat_message(const std::string& message) {
|
|||
send_packet(0x2000, packet);
|
||||
}
|
||||
|
||||
flyff::Pointer<flyff::Mover::Buff> find_skill_buff(const flyff::Pointer<flyff::Mover> &mover, uint32_t skill_index) {
|
||||
for (const auto &buff: mover->buffs) {
|
||||
if (buff->get_type() == flyff::Mover::Buff::BUFF_SKILL) {
|
||||
auto skill_property = reinterpret_cast<flyff::SkillProperty *>(
|
||||
static_cast<flyff::ObjectProperty *>(buff->property)
|
||||
);
|
||||
|
||||
if (!buff->is_removed && skill_property->id == skill_index)
|
||||
return buff;
|
||||
}
|
||||
}
|
||||
|
||||
return flyff::Pointer<flyff::Mover::Buff>(nullptr);
|
||||
}
|
||||
|
||||
template<size_t size>
|
||||
std::vector<uint32_t> check_rebuff(const flyff::Pointer<flyff::Mover> &player, const uint32_t (&buffs_to_check)[size]) {
|
||||
const auto &neuz = flyff::Neuz::instance();
|
||||
|
||||
auto result = std::vector<uint32_t>();
|
||||
for (const auto &skill_index: buffs_to_check) {
|
||||
const auto &buff = find_skill_buff(player, skill_index);
|
||||
const auto &skill_property = neuz.get_skill_property(skill_index);
|
||||
// If a buff is active
|
||||
if (buff) {
|
||||
auto player_skill_level = player->get_skill_level(skill_index);
|
||||
// For some reason it's one off...
|
||||
auto current_skill_level = buff->level + 1;
|
||||
auto buff_property = reinterpret_cast<flyff::SkillProperty *>(
|
||||
static_cast<flyff::ObjectProperty *>(buff->property)
|
||||
);
|
||||
|
||||
if (player_skill_level > current_skill_level) {
|
||||
// Always apply a higher buff.
|
||||
result.push_back(skill_index);
|
||||
} else if (buff->get_time_remaining() < 30 * 1000 && player_skill_level >= current_skill_level) {
|
||||
// Refresh the buff.
|
||||
result.push_back(skill_index);
|
||||
}
|
||||
} else {
|
||||
// Apply the buff.
|
||||
result.push_back(skill_index);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
flyff::Pointer<flyff::InventoryItem> find_first_equippable_item(const flyff::ItemKind3& item_kind) {
|
||||
const auto &neuz = flyff::Neuz::instance();
|
||||
const auto &player = neuz.player;
|
||||
|
||||
uint32_t highest_level = 0;
|
||||
flyff::InventoryItem const *highest = nullptr;
|
||||
for (const auto &item: player->inventory) {
|
||||
const auto &prop = item.property;
|
||||
|
||||
if (item.index < 168 && prop && prop->item_kind3 == item_kind && prop->required_level <= player->get_level() &&
|
||||
prop->required_level > highest_level) {
|
||||
highest = &item;
|
||||
highest_level = prop->required_level;
|
||||
}
|
||||
}
|
||||
|
||||
return flyff::Pointer<flyff::InventoryItem>(highest);
|
||||
}
|
||||
|
||||
|
||||
bool is_running = false;
|
||||
flyff::Vector3 start_position = {0};
|
||||
// The object property index of the monster to grind.
|
||||
int object_property_index = 0;
|
||||
|
||||
void on_keyup_hook(int event_type, const EmscriptenKeyboardEvent *event, void *user_data) {
|
||||
const auto &neuz = flyff::Neuz::instance();
|
||||
|
||||
if (event->keyCode == 220) {
|
||||
|
||||
// if (!main_hand || main_hand->item_kind3 != flyff::ItemProperty::CheerStick) {
|
||||
// const auto &stick = find_first_equippable_item(flyff::ItemProperty::CheerStick);
|
||||
//
|
||||
// if (stick) {
|
||||
// std::string str = "Found valid cheerstick: ";
|
||||
// str.append(neuz.get_text(stick->property->name));
|
||||
// neuz.show_message(str, {0, 0xFF, 0});
|
||||
//
|
||||
// use_item_in_inventory(stick->index);
|
||||
// }
|
||||
// }
|
||||
// std::cout << reinterpret_cast<void*>(static_cast<u32>(main_hand)) << " Weapon is required level: " << main_hand->required_level << std::endl;
|
||||
|
||||
// auto length = ((uintptr_t)player->buffs.end() - (uintptr_t)player->buffs.begin()) / 4;
|
||||
// std::cout << length << " buffs!" << std::endl;;
|
||||
// for(const auto& test : player->buffs) {
|
||||
// std::cout << "Buff with type " << test->get_type() << " and id " << reinterpret_cast<void*>(test->get_id()) << std::endl;
|
||||
|
||||
// if(test->get_type() == flyff::Mover::Buff::BUFF_SKILL) {
|
||||
// auto skill_property = reinterpret_cast<flyff::SkillProperty*>(
|
||||
// static_cast<flyff::ObjectProperty*>(test->property)
|
||||
// );
|
||||
|
||||
// std::cout << "BuffSkill "
|
||||
// << neuz.get_text(skill_property->name)
|
||||
// << " ReqLv. " << skill_property->required_level
|
||||
// << " Lv." << skill_property->level
|
||||
// << " Id: " << reinterpret_cast<void*>(skill_property->id)
|
||||
// << " Remaining: " << (test->get_time_remaining() / 1000)
|
||||
// << std::endl;
|
||||
// }
|
||||
// }
|
||||
|
||||
//
|
||||
// clear_target();
|
||||
// auto items = player->inventory.begin();
|
||||
// auto length = ((uintptr_t)player->inventory.end() - (uintptr_t)player->inventory.begin()) / 0x60;
|
||||
|
||||
// static constexpr int max_inventory_size = 168;
|
||||
// static constexpr int slot_weapon = max_inventory_size + 10;
|
||||
|
||||
// int stick_index = -1;
|
||||
// if(items[slot_weapon].index != -1 &&
|
||||
// items[slot_weapon].property &&
|
||||
// items[slot_weapon].property->item_kind3 == flyff::ItemProperty::CheerStick) {
|
||||
// stick_index = slot_weapon;
|
||||
// } else {
|
||||
// for(auto i = 0; i < length; i++) {
|
||||
// if(items[i].index != -1 && items[i].property) {
|
||||
// // if(items[i].index < 168) InventoryItem
|
||||
// // else Equipped
|
||||
|
||||
// // std::cout << items[i].index << std::endl;
|
||||
// std::cout << neuz.get_text(items[i].property->name) << " at " << items[i].index << ": "
|
||||
// << "IK2=" << items[i].property->item_kind2 << ", "
|
||||
// << "IK3=" << items[i].property->item_kind3
|
||||
// << std::endl;
|
||||
|
||||
// if(items[i].property->item_kind3 == flyff::ItemProperty::CheerStick) {
|
||||
// stick_index = i;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// if(stick_index != -1) {
|
||||
// // Switch main_hand
|
||||
// use_item_in_inventory(stick_index);
|
||||
// }
|
||||
// }
|
||||
|
||||
// if(stick_index != -1) {
|
||||
// // Use skill Heal
|
||||
// use_skill(0x2c, 10);
|
||||
// } else {
|
||||
// neuz.show_message("Could not find a stick to heal myself.", { 0xFF, 0, 0 });
|
||||
// }
|
||||
}
|
||||
|
||||
// BracketLeft
|
||||
if(event->keyCode == 219 && is_running == false) {
|
||||
if (event->keyCode == 219 && !is_running) {
|
||||
if (!neuz.player)
|
||||
return;
|
||||
|
||||
if (neuz.player->selected_target == 0) {
|
||||
neuz.show_message("No monster selected, unable to start bot.", {0xFF, 0, 0});
|
||||
return;
|
||||
}
|
||||
|
||||
auto target = neuz.get_mover(neuz.player->selected_target);
|
||||
if (!target) {
|
||||
neuz.show_message("No monster selected, unable to start bot.", {0xFF, 0xFF, 0});
|
||||
return;
|
||||
}
|
||||
|
||||
std::string str = "I'm only going to kill ";
|
||||
str.append(neuz.get_text(target->name));
|
||||
str.append("<Lv. ");
|
||||
str.append(std::to_string(target->get_level()));
|
||||
str.append(">");
|
||||
neuz.show_message(str);
|
||||
|
||||
object_property_index = target->property_id;
|
||||
start_position = {neuz.player->position.x, neuz.player->position.y, neuz.player->position.z};
|
||||
std::cout << "Start botting at " << start_position << std::endl;
|
||||
|
||||
|
|
@ -188,15 +367,13 @@ void on_keyup_hook(int event_type, const EmscriptenKeyboardEvent* event, void* u
|
|||
}
|
||||
|
||||
if (event->keyCode == 221) {
|
||||
if(is_running == true) {
|
||||
if (is_running) {
|
||||
is_running = false;
|
||||
|
||||
neuz.show_message("Bot stopped");
|
||||
} else {
|
||||
if (!neuz.player) return;
|
||||
|
||||
const auto& player = *neuz.player;
|
||||
|
||||
neuz.show_announcement("Hello world!", {0xFF, 0, 0});
|
||||
|
||||
auto current = neuz.movers.first;
|
||||
|
|
@ -211,6 +388,7 @@ void on_keyup_hook(int event_type, const EmscriptenKeyboardEvent* event, void* u
|
|||
<< (mover->is_fly() ? "Flying" : "Not flying") << ", "
|
||||
<< (mover->is_jumping() ? "Jumping" : "Not jumping") << ", "
|
||||
<< (mover->is_moving() ? "Moving" : "Not moving")
|
||||
<< (mover->is_grounded ? "On ground" : "Flying")
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
|
|
@ -253,9 +431,9 @@ flyff::MoverID attack_next_target(flyff::Vector3 const& start_position) {
|
|||
do {
|
||||
const auto &mover = current->mover;
|
||||
|
||||
auto dx = std::abs(mover->position.x - start_position.x);
|
||||
auto dy = std::abs(mover->position.y - start_position.y);
|
||||
auto dz = std::abs(mover->position.z - start_position.z);
|
||||
auto dx = std::abs(mover->position.x - neuz.player->position.x);
|
||||
auto dy = std::abs(mover->position.y - neuz.player->position.y);
|
||||
auto dz = std::abs(mover->position.z - neuz.player->position.z);
|
||||
|
||||
auto squared = (dx * dx) + (dy * dy) + (dz * dz);
|
||||
auto d = std::sqrt(squared);
|
||||
|
|
@ -263,14 +441,13 @@ flyff::MoverID attack_next_target(flyff::Vector3 const& start_position) {
|
|||
if (mover->type == ObjectType::Mover &&
|
||||
current->hash != neuz.player_object_id &&
|
||||
!mover->is_dead() &&
|
||||
// Only attack ground mobs.
|
||||
mover->is_grounded &&
|
||||
// Only attack same mobs.
|
||||
mover->property_id == object_property_index &&
|
||||
d <= max_distance) {
|
||||
// If it's a monster that has me targetted
|
||||
if(mover->last_attacked_target == neuz.player_object_id) {
|
||||
closest = mover;
|
||||
|
||||
std::cout << mover->name << " has attacked me, so I'm attacking" << std::endl;
|
||||
break;
|
||||
} else if(d < lowest_distance) {
|
||||
if (d < lowest_distance) {
|
||||
closest = mover;
|
||||
lowest_distance = d;
|
||||
}
|
||||
|
|
@ -296,7 +473,6 @@ flyff::MoverID find_next_item() {
|
|||
const auto &neuz = flyff::Neuz::instance();
|
||||
|
||||
if (!neuz.player) return 0;
|
||||
auto& player = *neuz.player;
|
||||
|
||||
float lowest_distance = 32.f;
|
||||
auto closest = flyff::Pointer<flyff::Mover>(nullptr);
|
||||
|
|
@ -305,8 +481,8 @@ flyff::MoverID find_next_item() {
|
|||
do {
|
||||
const auto &mover = current->mover;
|
||||
|
||||
auto dx = std::abs(mover->position.x - player.position.x);
|
||||
auto dz = std::abs(mover->position.z - player.position.z);
|
||||
auto dx = std::abs(mover->position.x - neuz.player->position.x);
|
||||
auto dz = std::abs(mover->position.z - neuz.player->position.z);
|
||||
|
||||
auto squared = (dx * dx) + (dz * dz);
|
||||
auto d = std::sqrt(squared);
|
||||
|
|
@ -316,25 +492,13 @@ flyff::MoverID find_next_item() {
|
|||
mover->type == ObjectType::Item &&
|
||||
d <= lowest_distance) {
|
||||
|
||||
flyff::ItemProperty* prop = reinterpret_cast<flyff::ItemProperty*>(
|
||||
auto *prop = reinterpret_cast<flyff::ItemProperty *>(
|
||||
static_cast<flyff::ObjectProperty *>(mover->property)
|
||||
);
|
||||
|
||||
if(prop->is_quest()) {
|
||||
std::string str = "Skipping ";
|
||||
str.append(neuz.get_text(prop->name));
|
||||
str.append(" because is quest item.");
|
||||
|
||||
neuz.show_message(str);
|
||||
} else {
|
||||
if (!prop->is_quest()) {
|
||||
closest = mover;
|
||||
lowest_distance = d;
|
||||
|
||||
std::string str = "";
|
||||
str.append(neuz.get_text(prop->name));
|
||||
str.append(" is close.");
|
||||
|
||||
neuz.show_message(str);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -386,6 +550,8 @@ void bot_tick() {
|
|||
return;
|
||||
}
|
||||
|
||||
const auto &player = neuz.player;
|
||||
|
||||
// if is_idle:
|
||||
// if item_target:
|
||||
// pickup_item()
|
||||
|
|
@ -420,9 +586,65 @@ void bot_tick() {
|
|||
|
||||
if (neuz.player->get_move_state() == 1 &&
|
||||
!neuz.player->is_attacking()) {
|
||||
|
||||
|
||||
// Check buffs.
|
||||
static constexpr uint32_t buffs_to_check[] = {
|
||||
flyff::SkillIndex::HeapUp,
|
||||
flyff::SkillIndex::Haste,
|
||||
flyff::SkillIndex::Patience
|
||||
};
|
||||
|
||||
auto item = neuz.get_mover(current_pickup_item);
|
||||
auto monster = neuz.get_mover(current_target);
|
||||
|
||||
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, buffs_to_check);
|
||||
if (!buffs.empty() && (!item || item->is_despawned) && (!monster || monster->is_dead())) {
|
||||
const auto next_buff = 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();
|
||||
|
||||
use_item_in_inventory(stick->index);
|
||||
use_skill(next_buff);
|
||||
return;
|
||||
} else {
|
||||
neuz.show_message("Unable to find a stick", {0xFF, 0, 0});
|
||||
}
|
||||
} else {
|
||||
buffs.pop_back();
|
||||
use_skill(next_buff);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (buffs.empty()) {
|
||||
if (!main_hand || main_hand->item_kind3 != flyff::ItemKind3::KnuckleHammer) {
|
||||
const auto &knuckle = find_first_equippable_item(flyff::ItemKind3::KnuckleHammer);
|
||||
|
||||
if (knuckle) {
|
||||
use_item_in_inventory(knuckle->index);
|
||||
} else {
|
||||
neuz.show_message("Unable to find a knuckle", {0xFF, 0, 0});
|
||||
}
|
||||
}
|
||||
|
||||
if (!off_hand || off_hand->item_kind3 != flyff::ItemKind3::Shield) {
|
||||
const auto &shield = find_first_equippable_item(flyff::ItemKind3::Shield);
|
||||
|
||||
if (shield) {
|
||||
use_item_in_inventory(shield->index);
|
||||
} else {
|
||||
neuz.show_message("Unable to find a shield", {0xFF, 0, 0});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (item && !item->is_despawned && neuz.player->move_toward_target == 0) {
|
||||
// Pickup
|
||||
interact(item->object_id);
|
||||
|
|
@ -433,15 +655,46 @@ void bot_tick() {
|
|||
} else if ((!item || item->is_despawned) &&
|
||||
(!monster || monster->is_dead())) {
|
||||
std::cout << "No item, no target. Searching..." << std::endl;
|
||||
|
||||
// First check all mobs if they attacked me (aggro ones).
|
||||
auto current = neuz.movers.first;
|
||||
do {
|
||||
const auto &mover = current->mover;
|
||||
|
||||
if (mover->type == ObjectType::Mover &&
|
||||
current->hash != neuz.player_object_id &&
|
||||
!mover->is_dead() &&
|
||||
// If it's a monster that has me targetted...
|
||||
mover->last_attacked_target == neuz.player_object_id &&
|
||||
// ...and is tracking me
|
||||
mover->follow_target == neuz.player_object_id) {
|
||||
|
||||
current_target = attack_next_target(start_position);
|
||||
|
||||
monster = neuz.get_mover(current_target);
|
||||
std::string str = "Attacking ";
|
||||
str.append(monster->name);
|
||||
str.append(" because it attacked me.");
|
||||
|
||||
interact(monster->object_id);
|
||||
|
||||
neuz.show_message(str);
|
||||
return;
|
||||
}
|
||||
|
||||
current = current->next;
|
||||
} while (current);
|
||||
|
||||
// No item target and no attack target
|
||||
current_pickup_item = find_next_item();
|
||||
item = neuz.get_mover(current_pickup_item);
|
||||
if (item) {
|
||||
// flyff::ItemProperty* prop = (flyff::ItemProperty*)static_cast<uintptr_t*>(current_pickup_item->property);
|
||||
flyff::ItemProperty *prop = reinterpret_cast<flyff::ItemProperty *>(
|
||||
static_cast<flyff::ObjectProperty *>(item->property)
|
||||
);
|
||||
|
||||
std::string str = "Picking up ";
|
||||
std::cout << str << std::endl;
|
||||
// str.append(prop->name);
|
||||
str.append(neuz.get_text(prop->name));
|
||||
|
||||
interact(item->object_id);
|
||||
|
||||
|
|
@ -466,39 +719,6 @@ void bot_tick() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static constexpr uint32_t PICKUP = flyff::Object::State::AtkAll | flyff::Object::State::Dead;
|
||||
|
||||
// if((current_pickup_item != nullptr &&
|
||||
// !current_pickup_item->is_despawned) ||
|
||||
// (neuz.player->object_state & PICKUP) != 0) {
|
||||
// // Wait
|
||||
// std::cout << "ObjectSTate & Pickup = " << reinterpret_cast<void*>(neuz.player->object_state & PICKUP) << std::endl;
|
||||
// } else if(current_target == nullptr) {
|
||||
// current_pickup_item = pickup_next_item();
|
||||
// if(current_pickup_item != nullptr) {
|
||||
// neuz.show_message("Picking up");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// current_target = attack_next_target(start_position);
|
||||
|
||||
// if(current_target) {
|
||||
// std::string str = "Attacking ";
|
||||
// str.append(current_target->name);
|
||||
|
||||
// neuz.show_message(str);
|
||||
// } else {
|
||||
// neuz.show_message("Unable to find target.");
|
||||
// }
|
||||
// } else if(current_target->is_dead()) {
|
||||
// current_target = nullptr;
|
||||
|
||||
// current_pickup_item = pickup_next_item();
|
||||
// if(current_pickup_item != nullptr) {
|
||||
// neuz.show_message("Picking up");
|
||||
// }
|
||||
// }
|
||||
} else {
|
||||
// Reset current target is not running.
|
||||
current_target = 0;
|
||||
|
|
|
|||
|
|
@ -7,175 +7,177 @@
|
|||
#include <AL/alc.h>
|
||||
|
||||
#include <fugg.h>
|
||||
#include <flyff.h>
|
||||
|
||||
#define TRACE_AL_CALLS 0
|
||||
|
||||
/* import: 'a' 'u' */
|
||||
// "u": "_alSourcef",
|
||||
WASM_IMPORT_IMPL(env, _alSourcef) = [](u32 a, u32 b, f32 c) {
|
||||
WASM_IMPORT_IMPL(env, _alSourcef) = [](u32 source, u32 param, f32 value) {
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alSourcef("
|
||||
<< a << ", "
|
||||
<< b << ", "
|
||||
<< c
|
||||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
alSourcef(a, b, c);
|
||||
};
|
||||
// "w": "_alSourcei",
|
||||
WASM_IMPORT_IMPL(env, _alSourcei) = [](u32 a, u32 b, u32 c) {
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alSourcei("
|
||||
<< a << ", "
|
||||
<< b << ", "
|
||||
<< c
|
||||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
alSourcei(a, b, c);
|
||||
};
|
||||
/* import: 'a' 'F' */
|
||||
/* _alSourceStop*/
|
||||
WASM_IMPORT_IMPL(env, _alSourceStop) = [](u32 a) {
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alSourceStop("
|
||||
<< a
|
||||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
alSourceStop(a);
|
||||
};
|
||||
// "L": "_alGetSourcei",
|
||||
WASM_IMPORT_IMPL(env, _alGetSourcei) = [](u32 a, u32 b, u32 c) {
|
||||
const auto& value = fugg::ModulePointer<ALint> { c };
|
||||
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alGetSourcei("
|
||||
<< a << ", "
|
||||
<< b << ", "
|
||||
<< source << ", "
|
||||
<< param << ", "
|
||||
<< value
|
||||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
alGetSourcei(a, b, value);
|
||||
alSourcef(source, static_cast<ALenum>(param), value);
|
||||
};
|
||||
// "w": "_alSourcei",
|
||||
WASM_IMPORT_IMPL(env, _alSourcei) = [](u32 source, u32 param, u32 value) {
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alSourcei("
|
||||
<< source << ", "
|
||||
<< param << ", "
|
||||
<< value
|
||||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
alSourcei(source, static_cast<ALenum>(param), static_cast<ALenum>(value));
|
||||
};
|
||||
/* import: 'a' 'F' */
|
||||
/* _alSourceStop*/
|
||||
WASM_IMPORT_IMPL(env, _alSourceStop) = [](u32 source) {
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alSourceStop("
|
||||
<< source
|
||||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
alSourceStop(source);
|
||||
};
|
||||
// "L": "_alGetSourcei",
|
||||
WASM_IMPORT_IMPL(env, _alGetSourcei) = [](u32 source, u32 param, u32 c) {
|
||||
const auto &value = flyff::Pointer<ALint>{c};
|
||||
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alGetSourcei("
|
||||
<< source << ", "
|
||||
<< param << ", "
|
||||
<< value
|
||||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
alGetSourcei(source, static_cast<ALenum>(param), static_cast<ALint *>(value));
|
||||
};
|
||||
/* import: 'a' 'Q' */
|
||||
// "Q": "_alDeleteSources"
|
||||
WASM_IMPORT_IMPL(env, _alDeleteSources) = [](u32 a, u32 b) {
|
||||
const auto& sources = fugg::ModulePointer<const ALuint> { b };
|
||||
WASM_IMPORT_IMPL(env, _alDeleteSources) = [](u32 n, u32 b) {
|
||||
const auto &sources = flyff::Pointer<const ALuint>{b};
|
||||
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alDeleteSources("
|
||||
<< a << ", "
|
||||
<< n << ", "
|
||||
<< sources
|
||||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
alDeleteSources(a, sources);
|
||||
alDeleteSources(static_cast<ALsizei>(n), static_cast<const ALuint *>(sources));
|
||||
};
|
||||
/* _alSource3f */
|
||||
WASM_IMPORT_IMPL(env, _alSource3f) = [](u32 a, u32 b, f32 c, f32 d, f32 e) {
|
||||
WASM_IMPORT_IMPL(env, _alSource3f) = [](u32 source, u32 param, f32 value1, f32 value2, f32 value3) {
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alSource3f("
|
||||
<< a << ", "
|
||||
<< b << ", "
|
||||
<< c << ", "
|
||||
<< d << ", "
|
||||
<< e
|
||||
<< source << ", "
|
||||
<< param << ", "
|
||||
<< value1 << ", "
|
||||
<< value2 << ", "
|
||||
<< value3
|
||||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
alSource3f(a, b, c, d, e);
|
||||
alSource3f(source, static_cast<ALenum>(param), value1, value2, value3);
|
||||
};
|
||||
/* import: 'a' 'bb' */
|
||||
// "bb": "_alSourcePlay",
|
||||
WASM_IMPORT_IMPL(env, _alSourcePlay) = [](u32 a) {
|
||||
WASM_IMPORT_IMPL(env, _alSourcePlay) = [](u32 source) {
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alSourcePlay("
|
||||
<< a
|
||||
<< source
|
||||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
alSourcePlay(a);
|
||||
alSourcePlay(source);
|
||||
};
|
||||
/* import: 'a' 'cb' */
|
||||
// "cb": "_alListenerfv",
|
||||
WASM_IMPORT_IMPL(env, _alListenerfv) = [](u32 a, u32 b) {
|
||||
const auto& values = fugg::ModulePointer<const ALfloat> { b };
|
||||
WASM_IMPORT_IMPL(env, _alListenerfv) = [](u32 param, u32 b) {
|
||||
const auto &values = flyff::Pointer<const ALfloat>{b};
|
||||
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alListenerfv("
|
||||
<< a << ", "
|
||||
<< param << ", "
|
||||
<< values
|
||||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
alListenerfv(a, values);
|
||||
alListenerfv(static_cast<ALenum>(param), static_cast<const ALfloat *>(values));
|
||||
};
|
||||
/* import: 'a' 'db' */
|
||||
// "db": "_alListener3f",
|
||||
WASM_IMPORT_IMPL(env, _alListener3f) = [](u32 a, f32 b, f32 c, f32 d) {
|
||||
WASM_IMPORT_IMPL(env, _alListener3f) = [](u32 param, f32 value1, f32 value2, f32 value3) {
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alListener3f("
|
||||
<< a << ", "
|
||||
<< b << ", "
|
||||
<< c << ", "
|
||||
<< d
|
||||
<< param << ", "
|
||||
<< value1 << ", "
|
||||
<< value2 << ", "
|
||||
<< value3
|
||||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
alListener3f(a, b, c, d);
|
||||
alListener3f(static_cast<ALenum>(param), value1, value2, value3);
|
||||
};
|
||||
/* import: 'a' 'Sb' */
|
||||
/* _alDeleteBuffers */
|
||||
WASM_IMPORT_IMPL(env, _alDeleteBuffers) = [](u32 a, u32 b) {
|
||||
const auto& buffers = fugg::ModulePointer<const ALuint> { b };
|
||||
WASM_IMPORT_IMPL(env, _alDeleteBuffers) = [](u32 n, u32 b) {
|
||||
const auto &buffers = flyff::Pointer<const ALuint>{b};
|
||||
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alDeleteBuffers("
|
||||
<< a << ", "
|
||||
<< n << ", "
|
||||
<< buffers
|
||||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
alDeleteBuffers(a, buffers);
|
||||
alDeleteBuffers(static_cast<ALsizei>(n), static_cast<const ALuint *>(buffers));
|
||||
};
|
||||
/* import: 'a' 'Tb' */
|
||||
/* _alBufferData */
|
||||
WASM_IMPORT_IMPL(env, _alBufferData) = [](u32 a, u32 b, u32 c, u32 d, u32 e) {
|
||||
const auto& data = fugg::ModulePointer<const ALvoid> { c };
|
||||
WASM_IMPORT_IMPL(env, _alBufferData) = [](u32 buffer, u32 format, u32 c, u32 size, u32 freq) {
|
||||
const auto &data = flyff::Pointer<const ALvoid>{c};
|
||||
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alBufferData("
|
||||
<< a << ", "
|
||||
<< b << ", "
|
||||
<< buffer << ", "
|
||||
<< format << ", "
|
||||
<< data << ", "
|
||||
<< d << ", "
|
||||
<< e
|
||||
<< size << ", "
|
||||
<< freq
|
||||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
alBufferData(a, b, data, d, e);
|
||||
alBufferData(buffer, static_cast<ALenum>(format), static_cast<const void *>(data), static_cast<ALsizei>(size),
|
||||
static_cast<ALsizei>(freq));
|
||||
};
|
||||
/* import: 'a' 'Ub' */
|
||||
// "Ub": "_alGenBuffers",
|
||||
WASM_IMPORT_IMPL(env, _alGenBuffers) = [](u32 a, u32 b) {
|
||||
const auto& buffers = fugg::ModulePointer<ALuint> { b };
|
||||
WASM_IMPORT_IMPL(env, _alGenBuffers) = [](u32 n, u32 b) {
|
||||
const auto &buffers = flyff::Pointer<ALuint>{b};
|
||||
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alGenBuffers("
|
||||
<< a << ", "
|
||||
<< n << ", "
|
||||
<< buffers
|
||||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
alGenBuffers(a, buffers);
|
||||
alGenBuffers(static_cast<ALsizei>(n), static_cast<ALuint *>(buffers));
|
||||
};
|
||||
/* import: 'a' 'Vb' */
|
||||
// "Vb": "_alGetEnumValue",
|
||||
WASM_IMPORT_IMPL(env, _alGetEnumValue) = [](u32 a) {
|
||||
const auto& ename = fugg::ModulePointer<const ALchar> { a };
|
||||
const auto &ename = flyff::Pointer<const ALchar>{a};
|
||||
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alGetEnumValue("
|
||||
|
|
@ -183,9 +185,7 @@ WASM_IMPORT_IMPL(env, _alGetEnumValue) = [](u32 a) {
|
|||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
return static_cast<u32>(
|
||||
alGetEnumValue(ename)
|
||||
);
|
||||
return static_cast<u32>(alGetEnumValue(static_cast<const ALchar *>(ename)));
|
||||
};
|
||||
/* import: 'a' 'Wb' */
|
||||
// "Wb": "_alcCloseDevice",
|
||||
|
|
@ -199,35 +199,33 @@ WASM_IMPORT_IMPL(env, _alcCloseDevice) = [](u32 a) {
|
|||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
return static_cast<u32>(
|
||||
alcCloseDevice(device)
|
||||
);
|
||||
return static_cast<u32>(alcCloseDevice(device));
|
||||
};
|
||||
/* import: 'a' 'Yb' */
|
||||
// "Yb": "_alGenSources",
|
||||
WASM_IMPORT_IMPL(env, _alGenSources) = [](u32 a, u32 b) {
|
||||
const auto& sources = fugg::ModulePointer<ALuint> { b };
|
||||
WASM_IMPORT_IMPL(env, _alGenSources) = [](u32 n, u32 b) {
|
||||
const auto &sources = flyff::Pointer<ALuint>{b};
|
||||
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alGenSources("
|
||||
<< a << ", "
|
||||
<< n << ", "
|
||||
<< sources
|
||||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
alGenSources(a, sources);
|
||||
alGenSources(static_cast<ALsizei>(n), static_cast<ALuint *>(sources));
|
||||
};
|
||||
/* import: 'a' 'Zb' */
|
||||
// "Zb": "_alListenerf",
|
||||
WASM_IMPORT_IMPL(env, _alListenerf) = [](u32 a, f32 b) {
|
||||
WASM_IMPORT_IMPL(env, _alListenerf) = [](u32 param, f32 value) {
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alListenerf("
|
||||
<< a << ", "
|
||||
<< b
|
||||
<< param << ", "
|
||||
<< value
|
||||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
alListenerf(a, b);
|
||||
alListenerf(static_cast<ALenum>(param), value);
|
||||
};
|
||||
/* import: 'a' '_b' */
|
||||
// "_b": "_alcMakeContextCurrent",
|
||||
|
|
@ -241,9 +239,7 @@ WASM_IMPORT_IMPL(env, _alcMakeContextCurrent) = [](u32 a) {
|
|||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
return static_cast<u32>(
|
||||
alcMakeContextCurrent(context)
|
||||
);
|
||||
return static_cast<u32>(alcMakeContextCurrent(context));
|
||||
};
|
||||
/* import: 'a' '$b' */
|
||||
/* _alcCreateContext */
|
||||
|
|
@ -259,9 +255,7 @@ WASM_IMPORT_IMPL(env, _alcCreateContext) = [](u32 a, u32 b) {
|
|||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
return reinterpret_cast<u32>(
|
||||
alcCreateContext(device, attr_list)
|
||||
);
|
||||
return reinterpret_cast<u32>(alcCreateContext(device, attr_list));
|
||||
};
|
||||
/* import: 'a' 'Xb' */
|
||||
// "Xb": "_alcDestroyContext",
|
||||
|
|
@ -280,7 +274,7 @@ WASM_IMPORT_IMPL(env, _alcDestroyContext) = [](u32 a) {
|
|||
/* import: 'a' 'ac' */
|
||||
// "ac": "_alcOpenDevice",
|
||||
WASM_IMPORT_IMPL(env, _alcOpenDevice) = [](u32 a) {
|
||||
const auto& devicename = fugg::ModulePointer<const ALchar> { a };
|
||||
const auto &devicename = flyff::Pointer<const ALchar>{a};
|
||||
|
||||
#if TRACE_AL_CALLS
|
||||
std::cout << "_alcOpenDevice("
|
||||
|
|
@ -288,7 +282,5 @@ WASM_IMPORT_IMPL(env, _alcOpenDevice) = [](u32 a) {
|
|||
<< ")" << std::endl;
|
||||
#endif
|
||||
|
||||
return reinterpret_cast<u32>(
|
||||
alcOpenDevice(devicename)
|
||||
);
|
||||
return reinterpret_cast<u32>(alcOpenDevice(static_cast<const ALchar *>(devicename)));
|
||||
};
|
||||
Reference in New Issue