Pre Halloween patch
This commit is contained in:
parent
ce380a92f6
commit
3b24a7e478
|
|
@ -12,8 +12,22 @@
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
|
|
||||||
|
|
||||||
namespace flyff {
|
namespace flyff {
|
||||||
|
namespace raw {
|
||||||
|
extern "C" {
|
||||||
|
// w2c_f410: CMover::GetHitPoint(PlayerObject* mover);
|
||||||
|
extern u32 w2c_f410(u32);
|
||||||
|
// w2c_f2454: CCooltimeMgr::CanUse(uint64_t* timers, ItemProperty* prop);
|
||||||
|
extern u32 w2c_f2454(u32, u32);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct __attribute__((packed)) Mover {
|
struct __attribute__((packed)) Mover {
|
||||||
|
static constexpr uint32_t MAX_PARAM = 82;
|
||||||
|
|
||||||
|
using Parameter = unsigned long;
|
||||||
|
|
||||||
using ObjectStateFlags = Object::StateFlags;
|
using ObjectStateFlags = Object::StateFlags;
|
||||||
using ObjectState = Object::State;
|
using ObjectState = Object::State;
|
||||||
|
|
||||||
|
|
@ -22,6 +36,9 @@ struct __attribute__((packed)) Mover {
|
||||||
DEFINE_MEMBER(52, u32, get_level);
|
DEFINE_MEMBER(52, u32, get_level);
|
||||||
DEFINE_MEMBER(56, u32, get_gender);
|
DEFINE_MEMBER(56, u32, get_gender);
|
||||||
|
|
||||||
|
DEFINE_MEMBER(144, u32, get_max_origin_hp);
|
||||||
|
DEFINE_MEMBER(148, u32, get_max_origin_mp);
|
||||||
|
|
||||||
const MinimumSize<220> __size;
|
const MinimumSize<220> __size;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -40,9 +57,13 @@ struct __attribute__((packed)) Mover {
|
||||||
DEFINE_MEMBER(216, bool, is_despawned);
|
DEFINE_MEMBER(216, bool, is_despawned);
|
||||||
DEFINE_MEMBER(352, MoverID, object_id);
|
DEFINE_MEMBER(352, MoverID, object_id);
|
||||||
|
|
||||||
|
DEFINE_MEMBER(920, Parameter, adjustParam[MAX_PARAM]);
|
||||||
|
DEFINE_MEMBER(1248, Parameter, changeParam[MAX_PARAM]);
|
||||||
|
|
||||||
DEFINE_MEMBER(2020, const String, name);
|
DEFINE_MEMBER(2020, const String, name);
|
||||||
|
|
||||||
DEFINE_MEMBER(1628, Vector3, move_target);
|
DEFINE_MEMBER(1628, Vector3, move_target);
|
||||||
|
DEFINE_MEMBER(1688, unsigned long long, last_combat);
|
||||||
|
|
||||||
DEFINE_MEMBER(1728, MoverID, move_toward_target);
|
DEFINE_MEMBER(1728, MoverID, move_toward_target);
|
||||||
DEFINE_MEMBER(1736, MoverID, last_attacked_target);
|
DEFINE_MEMBER(1736, MoverID, last_attacked_target);
|
||||||
|
|
@ -54,8 +75,11 @@ struct __attribute__((packed)) Mover {
|
||||||
DEFINE_MEMBER(1768, MoverID, current_attack_target);
|
DEFINE_MEMBER(1768, MoverID, current_attack_target);
|
||||||
DEFINE_MEMBER(1776, MoverID, platform_standing_on);
|
DEFINE_MEMBER(1776, MoverID, platform_standing_on);
|
||||||
|
|
||||||
|
DEFINE_MEMBER(1816, int, adj_param);
|
||||||
DEFINE_MEMBER(1820, uint32_t, server_tick);
|
DEFINE_MEMBER(1820, uint32_t, server_tick);
|
||||||
|
|
||||||
|
DEFINE_MEMBER(1840, int, hitpoints);
|
||||||
|
|
||||||
DEFINE_MEMBER(1792, int, current_animation);
|
DEFINE_MEMBER(1792, int, current_animation);
|
||||||
|
|
||||||
DEFINE_MEMBER(204, ObjectType, type);
|
DEFINE_MEMBER(204, ObjectType, type);
|
||||||
|
|
@ -74,9 +98,82 @@ struct __attribute__((packed)) Mover {
|
||||||
|
|
||||||
DEFINE_MEMBER(860, Vector<InventoryItem>, inventory);
|
DEFINE_MEMBER(860, Vector<InventoryItem>, inventory);
|
||||||
|
|
||||||
|
|
||||||
|
DEFINE_MEMBER(3324, uint64_t, last_food_time);
|
||||||
|
DEFINE_MEMBER(3348, uint64_t, last_refresher_time);
|
||||||
|
DEFINE_MEMBER(3356, uint64_t, last_vitaldrink_time);
|
||||||
|
|
||||||
const MinimumSize<4096> __size;
|
const MinimumSize<4096> __size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool can_use_item(const Pointer<ItemProperty>& property) {
|
||||||
|
return raw::w2c_f2454(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>(0x00032a18);
|
||||||
|
// 10 seconds
|
||||||
|
return now - last_combat < 10000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parameter get_param(uint32_t index, Parameter base) const {
|
||||||
|
Parameter changeParam = get_change_param(index);
|
||||||
|
if(changeParam != 0x7FFFFFFF)
|
||||||
|
return changeParam;
|
||||||
|
|
||||||
|
Parameter adjustParam = get_adjust_param(index);
|
||||||
|
if(adjustParam)
|
||||||
|
return base + adjustParam;
|
||||||
|
else
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parameter get_adjust_param(Parameter index) const {
|
||||||
|
// Find these values in CMover::Init
|
||||||
|
return adjustParam[index] ^ adj_param ^ 0x0554e725 + index * 0x41c64e6d;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parameter get_change_param(Parameter index) const {
|
||||||
|
return changeParam[index] ^ adj_param ^ index * 0x41c64e6d + 0xb5a52d1a;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 get_hp() const {
|
||||||
|
return raw::w2c_f410(kMemory.to_inside(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 get_max_hp() const {
|
||||||
|
static constexpr Parameter DST_HP_MAX = 0x2c;
|
||||||
|
static constexpr Parameter DST_HP_MAX_RATE = 0x35;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 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 {
|
||||||
|
using Fn = FunctionPointer<u32, u32, u32, u32>;
|
||||||
|
const auto& fn = fugg::function_ref<Fn>(vtable->get_max_origin_hp);
|
||||||
|
|
||||||
|
return fn(kMemory.to_inside(this), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// int get_max_hp() const {
|
||||||
|
// return raw::w2c_f410(kMemory.to_inside(this));
|
||||||
|
// }
|
||||||
|
|
||||||
uint32_t get_state() const {
|
uint32_t get_state() const {
|
||||||
return object_state;
|
return object_state;
|
||||||
}
|
}
|
||||||
|
|
@ -158,14 +255,11 @@ struct __attribute__((packed)) Mover {
|
||||||
return (object_state & ObjectState::TurnAll) != 0;
|
return (object_state & ObjectState::TurnAll) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// int32_t get_level() {
|
u32 get_level() {
|
||||||
// // The function itself works but I fear it returns wrong results.
|
const auto& fn = fugg::function_ref<FunctionPointer<u32, u32>>(vtable->get_level);
|
||||||
// // Npc = 1
|
|
||||||
// // Players = 0
|
|
||||||
// const auto& fn = fugg::function_ref<FunctionPointer<int32_t, Pointer<Mover>>>(vtable->get_level);
|
|
||||||
|
|
||||||
// return fn(Pointer<Mover>(this));
|
return fn(kMemory.to_inside(this));
|
||||||
// }
|
}
|
||||||
|
|
||||||
// int32_t get_gender() {
|
// int32_t get_gender() {
|
||||||
// // The function itself works but I fear it returns wrong results.
|
// // The function itself works but I fear it returns wrong results.
|
||||||
|
|
@ -176,12 +270,6 @@ struct __attribute__((packed)) Mover {
|
||||||
|
|
||||||
// return fn(Pointer<Mover>(this));
|
// return fn(Pointer<Mover>(this));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// bool prevents_pickup_emote() const {
|
|
||||||
// DEFINE_MEMBER(1806, uint16_t, pickup_flags);
|
|
||||||
// // Returns true if in attack animation
|
|
||||||
// return (pickup_flags & 0x8ff) != 0;
|
|
||||||
// }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MoverMap {
|
struct MoverMap {
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ void Neuz::show_message(const std::string& message,
|
||||||
auto color_ = std::make_unique<flyff::Color>(color);
|
auto color_ = std::make_unique<flyff::Color>(color);
|
||||||
|
|
||||||
raw::show_message(
|
raw::show_message(
|
||||||
static_cast<uintptr_t>(messages_ui),
|
static_cast<u32>(messages_ui),
|
||||||
fugg::RuntimePointer<fugg::String>(message_.get()).as_raw(),
|
fugg::RuntimePointer<fugg::String>(message_.get()).as_raw(),
|
||||||
fugg::RuntimePointer<flyff::Color>(color_.get()).as_raw());
|
fugg::RuntimePointer<flyff::Color>(color_.get()).as_raw());
|
||||||
}
|
}
|
||||||
|
|
@ -116,15 +116,15 @@ void Neuz::show_announcement(const std::string& message,
|
||||||
auto color_ = std::make_unique<flyff::Color>(color);
|
auto color_ = std::make_unique<flyff::Color>(color);
|
||||||
|
|
||||||
raw::show_announcement(
|
raw::show_announcement(
|
||||||
static_cast<uintptr_t>(announcements_ui),
|
static_cast<u32>(announcements_ui),
|
||||||
fugg::RuntimePointer<fugg::String>(message_.get()).as_raw(),
|
fugg::RuntimePointer<fugg::String>(message_.get()).as_raw(),
|
||||||
fugg::RuntimePointer<flyff::Color>(color_.get()).as_raw());
|
fugg::RuntimePointer<flyff::Color>(color_.get()).as_raw());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Neuz::is_valid_attack(const Pointer<Mover>& attacker,
|
bool Neuz::is_valid_attack(const Pointer<Mover>& attacker,
|
||||||
const Pointer<Mover>& defender) const {
|
const Pointer<Mover>& defender) const {
|
||||||
auto result = raw::w2c_f514(static_cast<uintptr_t>(attacker),
|
auto result = raw::w2c_f514(static_cast<u32>(attacker),
|
||||||
static_cast<uintptr_t>(defender));
|
static_cast<u32>(defender));
|
||||||
|
|
||||||
return result != 0;
|
return result != 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,10 @@ class Memory {
|
||||||
return offset != NULL ? offset - start() : NULL;
|
return offset != NULL ? offset - start() : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
intptr_t to_inside(const void* offset) {
|
||||||
|
return to_inside(reinterpret_cast<uintptr_t>(offset));
|
||||||
|
}
|
||||||
|
|
||||||
uintptr_t to_outside(const uintptr_t offset) {
|
uintptr_t to_outside(const uintptr_t offset) {
|
||||||
return offset != NULL ? reinterpret_cast<uintptr_t>(&(*memory)->data[offset]) : NULL;
|
return offset != NULL ? reinterpret_cast<uintptr_t>(&(*memory)->data[offset]) : NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -95,7 +99,7 @@ class __attribute__((packed)) Pointer {
|
||||||
return as_outside();
|
return as_outside();
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit operator uintptr_t() const {
|
explicit operator u32() const {
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -651,7 +651,7 @@ static u32 w2c_f406(u32);
|
||||||
static u32 w2c_f407(u32);
|
static u32 w2c_f407(u32);
|
||||||
static void w2c_f408(u32);
|
static void w2c_f408(u32);
|
||||||
static u32 w2c_f409(u32);
|
static u32 w2c_f409(u32);
|
||||||
static u32 w2c_f410(u32);
|
u32 w2c_f410(u32);
|
||||||
static void w2c_f411(u32, u32);
|
static void w2c_f411(u32, u32);
|
||||||
static u32 w2c_f412(u32);
|
static u32 w2c_f412(u32);
|
||||||
static u32 w2c_f413(u32, u32);
|
static u32 w2c_f413(u32, u32);
|
||||||
|
|
@ -2695,7 +2695,7 @@ static void w2c_f2450(u32, u32, u32, u32);
|
||||||
static void w2c_f2451(u32, u32, u32);
|
static void w2c_f2451(u32, u32, u32);
|
||||||
static u32 w2c_f2452(u32);
|
static u32 w2c_f2452(u32);
|
||||||
static u32 w2c_f2453(u32);
|
static u32 w2c_f2453(u32);
|
||||||
static u32 w2c_f2454(u32, u32);
|
u32 w2c_f2454(u32, u32);
|
||||||
static u32 w2c_f2455(u32);
|
static u32 w2c_f2455(u32);
|
||||||
static u32 w2c_f2456(u32);
|
static u32 w2c_f2456(u32);
|
||||||
static void w2c_f2457(void);
|
static void w2c_f2457(void);
|
||||||
|
|
@ -98640,7 +98640,7 @@ static u32 w2c_f409(u32 w2c_p0) {
|
||||||
return w2c_i0;
|
return w2c_i0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 w2c_f410(u32 w2c_p0) {
|
u32 w2c_f410(u32 w2c_p0) {
|
||||||
u32 w2c_l1 = 0, w2c_l2 = 0, w2c_l3 = 0;
|
u32 w2c_l1 = 0, w2c_l2 = 0, w2c_l3 = 0;
|
||||||
f32 w2c_l4 = 0;
|
f32 w2c_l4 = 0;
|
||||||
FUNC_PROLOGUE;
|
FUNC_PROLOGUE;
|
||||||
|
|
@ -1095840,7 +1095840,7 @@ static u32 w2c_f2453(u32 w2c_p0) {
|
||||||
return w2c_i0;
|
return w2c_i0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 w2c_f2454(u32 w2c_p0, u32 w2c_p1) {
|
u32 w2c_f2454(u32 w2c_p0, u32 w2c_p1) {
|
||||||
u32 w2c_l2 = 0, w2c_l3 = 0;
|
u32 w2c_l2 = 0, w2c_l3 = 0;
|
||||||
u64 w2c_l4 = 0;
|
u64 w2c_l4 = 0;
|
||||||
FUNC_PROLOGUE;
|
FUNC_PROLOGUE;
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,7 @@ namespace fugg
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr const uint32_t hash_to_id(const uint32_t hashed) {
|
constexpr const uint32_t hash_to_id(const uint32_t hashed) {
|
||||||
constexpr uint32_t header_hash = 0x644ab400;
|
return hashed ^ flyff::PACKET_HEADER_HASH;
|
||||||
|
|
||||||
return hashed ^ header_hash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
@ -208,7 +206,7 @@ void on_keyup_hook(int event_type, const EmscriptenKeyboardEvent* event, void* u
|
||||||
if(mover->type == ObjectType::Mover) {
|
if(mover->type == ObjectType::Mover) {
|
||||||
// int level = mover->get_level();
|
// int level = mover->get_level();
|
||||||
|
|
||||||
std::cout << neuz.get_text(mover->name) << ": "
|
std::cout << neuz.get_text(mover->name) << " <Lv. " << mover->get_level() << ">): "
|
||||||
<< (mover->is_dead() ? "Dead" : "Not dead") << ", "
|
<< (mover->is_dead() ? "Dead" : "Not dead") << ", "
|
||||||
<< (mover->is_fly() ? "Flying" : "Not flying") << ", "
|
<< (mover->is_fly() ? "Flying" : "Not flying") << ", "
|
||||||
<< (mover->is_jumping() ? "Jumping" : "Not jumping") << ", "
|
<< (mover->is_jumping() ? "Jumping" : "Not jumping") << ", "
|
||||||
|
|
@ -358,10 +356,10 @@ void interact(const flyff::MoverID& id) {
|
||||||
if(!neuz.player)
|
if(!neuz.player)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// neuz.player->selected_target = id;
|
neuz.player->selected_target = id;
|
||||||
set_target(id);
|
set_target(id);
|
||||||
|
|
||||||
// neuz.player->move_toward_target = id;
|
neuz.player->move_toward_target = id;
|
||||||
interact_target(1);
|
interact_target(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -374,6 +372,16 @@ void bot_tick() {
|
||||||
if(!neuz.player)
|
if(!neuz.player)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// std::cout << "Max Max HP: "
|
||||||
|
// << neuz.player->get_max_hp()
|
||||||
|
// << ", Adjust HP:"
|
||||||
|
// << neuz.player->get_adjust_param(0x2c)
|
||||||
|
// << ", Player level: "
|
||||||
|
// << neuz.player->get_level()
|
||||||
|
// << std::endl;
|
||||||
|
|
||||||
|
// printf("%#010x\n", neuz.player->get_state());
|
||||||
|
|
||||||
if(is_running) {
|
if(is_running) {
|
||||||
if(neuz.player->is_dead()) {
|
if(neuz.player->is_dead()) {
|
||||||
neuz.show_message("Player is dead, stopping...", {0xFF, 0x00, 0x00});
|
neuz.show_message("Player is dead, stopping...", {0xFF, 0x00, 0x00});
|
||||||
|
|
@ -389,10 +397,31 @@ void bot_tick() {
|
||||||
|
|
||||||
if(neuz.player->get_move_state() == 1 &&
|
if(neuz.player->get_move_state() == 1 &&
|
||||||
!neuz.player->is_attacking()) {
|
!neuz.player->is_attacking()) {
|
||||||
if(current_pickup_item != nullptr && !current_pickup_item->is_despawned && neuz.player->move_toward_target == 0) {
|
|
||||||
|
if(neuz.player->get_hp_percent() < 75) {
|
||||||
|
neuz.show_message("Fooding because HP is under 75%");
|
||||||
|
|
||||||
|
const auto& player = neuz.player;
|
||||||
|
|
||||||
|
auto items = player->inventory.begin();
|
||||||
|
auto length = ((uintptr_t)player->inventory.end() - (uintptr_t)player->inventory.begin()) / 0x60;
|
||||||
|
|
||||||
|
for(auto i = 0; i < length; i++) {
|
||||||
|
if(items[i].index != -1 &&
|
||||||
|
items[i].property &&
|
||||||
|
items[i].property->is_food_item() &&
|
||||||
|
player->can_use_item(items[i].property)) {
|
||||||
|
neuz.show_message(neuz.get_text(items[i].property->name));
|
||||||
|
|
||||||
|
use_item_in_inventory(i);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(current_pickup_item != nullptr && !current_pickup_item->is_despawned && neuz.player->move_toward_target == 0) {
|
||||||
// Pickup
|
// Pickup
|
||||||
interact(current_pickup_item->object_id);
|
interact(current_pickup_item->object_id);
|
||||||
} else if(current_target && !current_target->is_dead() && neuz.player->attack_target == 0) {
|
} else if(current_target && !current_target->is_dead() && neuz.player->attack_target == 0 && neuz.player->move_toward_target == 0) {
|
||||||
// Attack
|
// Attack
|
||||||
interact(current_target->object_id);
|
interact(current_target->object_id);
|
||||||
// neuz.player->attack_target = current_target->object_id;
|
// neuz.player->attack_target = current_target->object_id;
|
||||||
|
|
@ -410,24 +439,23 @@ void bot_tick() {
|
||||||
|
|
||||||
interact(current_pickup_item->object_id);
|
interact(current_pickup_item->object_id);
|
||||||
|
|
||||||
neuz.show_message(str);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
current_target = attack_next_target(start_position);
|
|
||||||
|
|
||||||
if(current_target) {
|
|
||||||
std::string str = "Attacking ";
|
|
||||||
str.append(current_target->name);
|
|
||||||
|
|
||||||
std::cout << str << std::endl;
|
|
||||||
|
|
||||||
interact(current_target->object_id);
|
|
||||||
neuz.player->attack_target = current_target->object_id;
|
|
||||||
|
|
||||||
neuz.show_message(str);
|
neuz.show_message(str);
|
||||||
} else {
|
} else {
|
||||||
neuz.show_message("Unable to find target.");
|
current_target = attack_next_target(start_position);
|
||||||
|
|
||||||
|
if(current_target) {
|
||||||
|
std::string str = "Attacking ";
|
||||||
|
str.append(current_target->name);
|
||||||
|
|
||||||
|
std::cout << str << std::endl;
|
||||||
|
|
||||||
|
interact(current_target->object_id);
|
||||||
|
neuz.player->attack_target = current_target->object_id;
|
||||||
|
|
||||||
|
neuz.show_message(str);
|
||||||
|
} else {
|
||||||
|
neuz.show_message("Unable to find target.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Reference in New Issue