Pre Halloween patch
This commit is contained in:
parent
ce380a92f6
commit
3b24a7e478
|
|
@ -12,8 +12,22 @@
|
|||
#include "math.h"
|
||||
#include "item.h"
|
||||
|
||||
|
||||
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 {
|
||||
static constexpr uint32_t MAX_PARAM = 82;
|
||||
|
||||
using Parameter = unsigned long;
|
||||
|
||||
using ObjectStateFlags = Object::StateFlags;
|
||||
using ObjectState = Object::State;
|
||||
|
||||
|
|
@ -22,6 +36,9 @@ struct __attribute__((packed)) Mover {
|
|||
DEFINE_MEMBER(52, u32, get_level);
|
||||
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;
|
||||
};
|
||||
};
|
||||
|
|
@ -40,9 +57,13 @@ struct __attribute__((packed)) Mover {
|
|||
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(2020, const String, name);
|
||||
|
||||
DEFINE_MEMBER(1628, Vector3, move_target);
|
||||
DEFINE_MEMBER(1688, unsigned long long, last_combat);
|
||||
|
||||
DEFINE_MEMBER(1728, MoverID, move_toward_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(1776, MoverID, platform_standing_on);
|
||||
|
||||
DEFINE_MEMBER(1816, int, adj_param);
|
||||
DEFINE_MEMBER(1820, uint32_t, server_tick);
|
||||
|
||||
DEFINE_MEMBER(1840, int, hitpoints);
|
||||
|
||||
DEFINE_MEMBER(1792, int, current_animation);
|
||||
|
||||
DEFINE_MEMBER(204, ObjectType, type);
|
||||
|
|
@ -74,9 +98,82 @@ struct __attribute__((packed)) Mover {
|
|||
|
||||
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;
|
||||
};
|
||||
|
||||
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 {
|
||||
return object_state;
|
||||
}
|
||||
|
|
@ -158,14 +255,11 @@ struct __attribute__((packed)) Mover {
|
|||
return (object_state & ObjectState::TurnAll) != 0;
|
||||
}
|
||||
|
||||
// int32_t get_level() {
|
||||
// // The function itself works but I fear it returns wrong results.
|
||||
// // Npc = 1
|
||||
// // Players = 0
|
||||
// const auto& fn = fugg::function_ref<FunctionPointer<int32_t, Pointer<Mover>>>(vtable->get_level);
|
||||
u32 get_level() {
|
||||
const auto& fn = fugg::function_ref<FunctionPointer<u32, u32>>(vtable->get_level);
|
||||
|
||||
// return fn(Pointer<Mover>(this));
|
||||
// }
|
||||
return fn(kMemory.to_inside(this));
|
||||
}
|
||||
|
||||
// int32_t get_gender() {
|
||||
// // The function itself works but I fear it returns wrong results.
|
||||
|
|
@ -176,12 +270,6 @@ struct __attribute__((packed)) Mover {
|
|||
|
||||
// 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 {
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ void Neuz::show_message(const std::string& message,
|
|||
auto color_ = std::make_unique<flyff::Color>(color);
|
||||
|
||||
raw::show_message(
|
||||
static_cast<uintptr_t>(messages_ui),
|
||||
static_cast<u32>(messages_ui),
|
||||
fugg::RuntimePointer<fugg::String>(message_.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);
|
||||
|
||||
raw::show_announcement(
|
||||
static_cast<uintptr_t>(announcements_ui),
|
||||
static_cast<u32>(announcements_ui),
|
||||
fugg::RuntimePointer<fugg::String>(message_.get()).as_raw(),
|
||||
fugg::RuntimePointer<flyff::Color>(color_.get()).as_raw());
|
||||
}
|
||||
|
||||
bool Neuz::is_valid_attack(const Pointer<Mover>& attacker,
|
||||
const Pointer<Mover>& defender) const {
|
||||
auto result = raw::w2c_f514(static_cast<uintptr_t>(attacker),
|
||||
static_cast<uintptr_t>(defender));
|
||||
auto result = raw::w2c_f514(static_cast<u32>(attacker),
|
||||
static_cast<u32>(defender));
|
||||
|
||||
return result != 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,10 @@ class Memory {
|
|||
uintptr_t to_inside(const uintptr_t offset) {
|
||||
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) {
|
||||
return offset != NULL ? reinterpret_cast<uintptr_t>(&(*memory)->data[offset]) : NULL;
|
||||
|
|
@ -95,7 +99,7 @@ class __attribute__((packed)) Pointer {
|
|||
return as_outside();
|
||||
}
|
||||
|
||||
explicit operator uintptr_t() const {
|
||||
explicit operator u32() const {
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -651,7 +651,7 @@ static u32 w2c_f406(u32);
|
|||
static u32 w2c_f407(u32);
|
||||
static void w2c_f408(u32);
|
||||
static u32 w2c_f409(u32);
|
||||
static u32 w2c_f410(u32);
|
||||
u32 w2c_f410(u32);
|
||||
static void w2c_f411(u32, u32);
|
||||
static u32 w2c_f412(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 u32 w2c_f2452(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_f2456(u32);
|
||||
static void w2c_f2457(void);
|
||||
|
|
@ -98640,7 +98640,7 @@ static u32 w2c_f409(u32 w2c_p0) {
|
|||
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;
|
||||
f32 w2c_l4 = 0;
|
||||
FUNC_PROLOGUE;
|
||||
|
|
@ -1095840,7 +1095840,7 @@ static u32 w2c_f2453(u32 w2c_p0) {
|
|||
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;
|
||||
u64 w2c_l4 = 0;
|
||||
FUNC_PROLOGUE;
|
||||
|
|
|
|||
|
|
@ -9,10 +9,8 @@ namespace fugg
|
|||
{
|
||||
}
|
||||
|
||||
constexpr const uint32_t hash_to_id(const uint32_t hashed) {
|
||||
constexpr uint32_t header_hash = 0x644ab400;
|
||||
|
||||
return hashed ^ header_hash;
|
||||
constexpr const uint32_t hash_to_id(const uint32_t hashed) {
|
||||
return hashed ^ flyff::PACKET_HEADER_HASH;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
|
@ -208,7 +206,7 @@ void on_keyup_hook(int event_type, const EmscriptenKeyboardEvent* event, void* u
|
|||
if(mover->type == ObjectType::Mover) {
|
||||
// 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_fly() ? "Flying" : "Not flying") << ", "
|
||||
<< (mover->is_jumping() ? "Jumping" : "Not jumping") << ", "
|
||||
|
|
@ -358,10 +356,10 @@ void interact(const flyff::MoverID& id) {
|
|||
if(!neuz.player)
|
||||
return;
|
||||
|
||||
// neuz.player->selected_target = id;
|
||||
neuz.player->selected_target = id;
|
||||
set_target(id);
|
||||
|
||||
// neuz.player->move_toward_target = id;
|
||||
neuz.player->move_toward_target = id;
|
||||
interact_target(1);
|
||||
}
|
||||
|
||||
|
|
@ -374,6 +372,16 @@ void bot_tick() {
|
|||
if(!neuz.player)
|
||||
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(neuz.player->is_dead()) {
|
||||
neuz.show_message("Player is dead, stopping...", {0xFF, 0x00, 0x00});
|
||||
|
|
@ -389,10 +397,31 @@ void bot_tick() {
|
|||
|
||||
if(neuz.player->get_move_state() == 1 &&
|
||||
!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
|
||||
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
|
||||
interact(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);
|
||||
|
||||
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);
|
||||
} 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