Some refactors after installing CLion

This commit is contained in:
Knaapchen 2022-10-22 01:33:40 +02:00
parent 9af9d664f5
commit 97169c715f
11 changed files with 1088 additions and 710 deletions

View File

@ -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"

View File

@ -5,6 +5,7 @@
// #include "../src/api.h"
#include "../src/Neuz.h"
#include "../src/Mover.h"
#include "../src/skill.h"
#include "../src/import.h"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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