Added AttackRange enum
Added CObj::IsRangeObj to check if an object is in range Identified more ItemKind2 and ItemKind3's Added get_attack_range to Mover
This commit is contained in:
parent
0899e2ed3a
commit
2fa1a801a3
|
|
@ -8,7 +8,7 @@ add_library(
|
||||||
"include/flyff.h"
|
"include/flyff.h"
|
||||||
src/core.h
|
src/core.h
|
||||||
src/skill/SkillProperty.h
|
src/skill/SkillProperty.h
|
||||||
src/object/ObjectProperty.h src/item/ItemKind2.h src/item/ItemKind3.h src/item/Part.h src/item/InventoryItem.h src/object/mover/JobProperty.h src/object/mover/ParamID.h src/object/mover/MoverProperty.h src/object/mover/Rank.h src/object/mover/Element.h)
|
src/object/ObjectProperty.h src/item/ItemKind2.h src/item/ItemKind3.h src/item/Part.h src/item/InventoryItem.h src/object/mover/JobProperty.h src/object/mover/ParamID.h src/object/mover/MoverProperty.h src/object/mover/Rank.h src/object/mover/Element.h src/item/AttackRange.h)
|
||||||
|
|
||||||
target_include_directories(flyff-api PUBLIC "include")
|
target_include_directories(flyff-api PUBLIC "include")
|
||||||
target_link_libraries(flyff-api PUBLIC flyff-client fugg-api)
|
target_link_libraries(flyff-api PUBLIC flyff-client fugg-api)
|
||||||
|
|
@ -22,17 +22,17 @@ namespace flyff {
|
||||||
static constexpr uintptr_t MAYBE_LOGIN_TIME = START_TIME + 8;
|
static constexpr uintptr_t MAYBE_LOGIN_TIME = START_TIME + 8;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// get_mover
|
// get_mover
|
||||||
extern u32 w2c_f208(u64);
|
extern u32 w2c_f208(u64);
|
||||||
// get_text
|
// get_text
|
||||||
extern void w2c_f167(u32, u32);
|
extern void w2c_f167(u32, u32);
|
||||||
// show_message
|
// show_message
|
||||||
extern void w2c_f341(u32, u32, u32);
|
extern void w2c_f341(u32, u32, u32);
|
||||||
// show_announcement
|
// show_announcement
|
||||||
extern void w2c_f607(u32, u32, u32);
|
extern void w2c_f607(u32, u32, u32);
|
||||||
// can_attack_target
|
// can_attack_target
|
||||||
extern u32 w2c_f515(u32, u32);
|
extern u32 w2c_f515(u32, u32);
|
||||||
// CProject::GetSkillProp()
|
// CProject::GetSkillProp()
|
||||||
extern u32 w2c_f440(u32, u32);
|
extern u32 w2c_f440(u32, u32);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,28 @@ namespace flyff {
|
||||||
// return Pointer<T>(new T(std::forward<Args>(args)...));
|
// return Pointer<T>(new T(std::forward<Args>(args)...));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template<typename I, typename O>
|
||||||
|
struct ArrowProxy {
|
||||||
|
I value;
|
||||||
|
|
||||||
|
O *operator->() {
|
||||||
|
return reinterpret_cast<O *>(&value);
|
||||||
|
}
|
||||||
|
|
||||||
|
O &operator*() {
|
||||||
|
return *(operator->)();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct RawVector {
|
||||||
|
T *begin;
|
||||||
|
T *end;
|
||||||
|
T *capacity;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
class __attribute__((packed)) String {
|
class __attribute__((packed)) String {
|
||||||
union {
|
union {
|
||||||
DEFINE_MEMBER(0x0, char*, text);
|
DEFINE_MEMBER(0x0, char*, text);
|
||||||
|
|
@ -167,6 +189,8 @@ namespace flyff {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class __attribute__((packed)) Vector {
|
class __attribute__((packed)) Vector {
|
||||||
|
using RawVector = detail::RawVector<T>;
|
||||||
|
|
||||||
// const Pointer<T>& begin_;
|
// const Pointer<T>& begin_;
|
||||||
// const Pointer<T>& end_;
|
// const Pointer<T>& end_;
|
||||||
// const Pointer<T>& capacity_;
|
// const Pointer<T>& capacity_;
|
||||||
|
|
@ -180,7 +204,17 @@ namespace flyff {
|
||||||
typedef T *iterator;
|
typedef T *iterator;
|
||||||
typedef const T *const_iterator;
|
typedef const T *const_iterator;
|
||||||
|
|
||||||
// This has to be const until strings can allocate...
|
detail::ArrowProxy<RawVector, std::vector<T>> operator->() const {
|
||||||
|
auto temp = RawVector{
|
||||||
|
.begin = static_cast<T *>(begin_),
|
||||||
|
.end = static_cast<T *>(end_),
|
||||||
|
.capacity = static_cast<T *>(capacity_),
|
||||||
|
};
|
||||||
|
|
||||||
|
return {temp};
|
||||||
|
}
|
||||||
|
|
||||||
|
// This has to be const until vectors can allocate...
|
||||||
T *begin() const {
|
T *begin() const {
|
||||||
return static_cast<T *>(begin_);
|
return static_cast<T *>(begin_);
|
||||||
}
|
}
|
||||||
|
|
@ -190,7 +224,9 @@ namespace flyff {
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
return static_cast<size_t>(end_ - begin_);
|
return static_cast<size_t>(
|
||||||
|
static_cast<flyff::MoverID *>(end_) - static_cast<flyff::MoverID *>(begin_)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
//
|
||||||
|
// Created by main on 15-11-22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef FUGG_ATTACKRANGE_H
|
||||||
|
#define FUGG_ATTACKRANGE_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace flyff {
|
||||||
|
enum class AttackRange : uint32_t {
|
||||||
|
// one-handed melee weapon
|
||||||
|
Short = 1,
|
||||||
|
// two-handed melee weapon
|
||||||
|
Long,
|
||||||
|
// weapons such as whips and spears
|
||||||
|
Far,
|
||||||
|
// Shooting Weapon
|
||||||
|
Range,
|
||||||
|
// wand distance
|
||||||
|
Wand,
|
||||||
|
//shooting weapon
|
||||||
|
HRange,
|
||||||
|
// long wand distance
|
||||||
|
HWand,
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::ostream &operator<<(std::ostream &os, const AttackRange &kind) {
|
||||||
|
switch (kind) {
|
||||||
|
case AttackRange::Short:
|
||||||
|
os << "Short";
|
||||||
|
break;
|
||||||
|
case AttackRange::Long:
|
||||||
|
os << "Long";
|
||||||
|
break;
|
||||||
|
case AttackRange::Far:
|
||||||
|
os << "Far";
|
||||||
|
break;
|
||||||
|
case AttackRange::Range:
|
||||||
|
os << "Range";
|
||||||
|
break;
|
||||||
|
case AttackRange::Wand:
|
||||||
|
os << "Wand";
|
||||||
|
break;
|
||||||
|
case AttackRange::HRange:
|
||||||
|
os << "HRange";
|
||||||
|
break;
|
||||||
|
case AttackRange::HWand:
|
||||||
|
os << "HWand";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
os << "AttackRange(" << static_cast<unsigned>(kind) << ")";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //FUGG_ATTACKRANGE_H
|
||||||
|
|
@ -10,20 +10,16 @@
|
||||||
namespace flyff {
|
namespace flyff {
|
||||||
enum class ItemKind2 : uint32_t {
|
enum class ItemKind2 : uint32_t {
|
||||||
// from https://api.flyff.com/#tag/item
|
// from https://api.flyff.com/#tag/item
|
||||||
|
// Remove those which are identified.
|
||||||
// "weapon"
|
// "weapon"
|
||||||
// "armor"
|
// "armor"
|
||||||
// "fashion"
|
// "fashion"
|
||||||
// "jewelry"
|
|
||||||
// "flying"
|
// "flying"
|
||||||
// "collector"
|
// "collector"
|
||||||
// "quest"
|
|
||||||
// "trans"
|
// "trans"
|
||||||
// "fuel"
|
// "fuel"
|
||||||
// "booty"
|
// "booty"
|
||||||
// "arrow"
|
|
||||||
// "charm"
|
// "charm"
|
||||||
// "recovery"
|
|
||||||
// "blinkwing"
|
|
||||||
// "firework"
|
// "firework"
|
||||||
// "pickuppet"
|
// "pickuppet"
|
||||||
// "teleportring"
|
// "teleportring"
|
||||||
|
|
@ -34,7 +30,10 @@ namespace flyff {
|
||||||
// "scroll"
|
// "scroll"
|
||||||
// "vendorskin"
|
// "vendorskin"
|
||||||
// "raisedpet"
|
// "raisedpet"
|
||||||
|
Jewelry = 5,
|
||||||
|
Arrow = 12,
|
||||||
Recovery = 14,
|
Recovery = 14,
|
||||||
|
Blinkwing = 15,
|
||||||
Quest = 25,
|
Quest = 25,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,11 @@ namespace flyff {
|
||||||
// "board"
|
// "board"
|
||||||
// "book"
|
// "book"
|
||||||
// "boots"
|
// "boots"
|
||||||
// "bow"
|
|
||||||
// "broom"
|
// "broom"
|
||||||
// "car"
|
// "car"
|
||||||
// "cloak"
|
// "cloak"
|
||||||
// "cloth"
|
// "cloth"
|
||||||
// "drink"
|
// "drink"
|
||||||
// "earring"
|
|
||||||
// "elementcard"
|
// "elementcard"
|
||||||
// "event"
|
// "event"
|
||||||
// "food"
|
// "food"
|
||||||
|
|
@ -38,27 +36,19 @@ namespace flyff {
|
||||||
// "letter"
|
// "letter"
|
||||||
// "mask"
|
// "mask"
|
||||||
// "mineral"
|
// "mineral"
|
||||||
// "necklace"
|
|
||||||
// "petfeed"
|
// "petfeed"
|
||||||
// "piercingcard"
|
// "piercingcard"
|
||||||
// "piercingdice"
|
// "piercingdice"
|
||||||
// "pill"
|
|
||||||
// "protectscroll"
|
// "protectscroll"
|
||||||
// "randomscroll"
|
// "randomscroll"
|
||||||
// "refresher"
|
// "refresher"
|
||||||
// "ring"
|
|
||||||
// "shield"
|
|
||||||
// "shoes"
|
// "shoes"
|
||||||
// "specialstone"
|
// "specialstone"
|
||||||
// "staff"
|
|
||||||
// "suit"
|
// "suit"
|
||||||
// "sword"
|
|
||||||
// "townblinkwing"
|
// "townblinkwing"
|
||||||
// "trans"
|
// "trans"
|
||||||
// "upgradedice"
|
// "upgradedice"
|
||||||
// "wand"
|
|
||||||
// "wings"
|
// "wings"
|
||||||
// "yoyo"
|
|
||||||
// "gacha"
|
// "gacha"
|
||||||
// "globalgacha"
|
// "globalgacha"
|
||||||
// "giftbox"
|
// "giftbox"
|
||||||
|
|
@ -76,12 +66,24 @@ namespace flyff {
|
||||||
// "raisedpet"
|
// "raisedpet"
|
||||||
// "raisedpettransmute"
|
// "raisedpettransmute"
|
||||||
// "harvestglove"
|
// "harvestglove"
|
||||||
|
Sword = 200,
|
||||||
|
|
||||||
Stick = 202,
|
Stick = 202,
|
||||||
Knuckle = 203,
|
Knuckle = 203,
|
||||||
|
Wand = 204,
|
||||||
|
Staff = 205,
|
||||||
|
Yoyo = 206,
|
||||||
|
Bow = 207,
|
||||||
|
|
||||||
Shield = 300,
|
Shield = 300,
|
||||||
|
|
||||||
HealthPill = 1404
|
|
||||||
|
Earring = 500,
|
||||||
|
Necklace = 501,
|
||||||
|
Ring = 502,
|
||||||
|
|
||||||
|
|
||||||
|
Pill = 1404
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::ostream &operator<<(std::ostream &os, const ItemKind3 &kind) {
|
static std::ostream &operator<<(std::ostream &os, const ItemKind3 &kind) {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "ItemKind2.h"
|
#include "ItemKind2.h"
|
||||||
#include "ItemKind3.h"
|
#include "ItemKind3.h"
|
||||||
|
#include "AttackRange.h"
|
||||||
|
|
||||||
namespace flyff {
|
namespace flyff {
|
||||||
struct __attribute__((packed)) ItemProperty {
|
struct __attribute__((packed)) ItemProperty {
|
||||||
|
|
@ -30,6 +31,7 @@ namespace flyff {
|
||||||
DEFINE_MEMBER(180, const flyff::String, description);
|
DEFINE_MEMBER(180, const flyff::String, description);
|
||||||
|
|
||||||
DEFINE_MEMBER(244, const uint32_t, required_level);
|
DEFINE_MEMBER(244, const uint32_t, required_level);
|
||||||
|
DEFINE_MEMBER(256, const AttackRange, attack_range);
|
||||||
|
|
||||||
DEFINE_MEMBER(348, const ItemKind2, item_kind2);
|
DEFINE_MEMBER(348, const ItemKind2, item_kind2);
|
||||||
DEFINE_MEMBER(352, const ItemKind3, item_kind3);
|
DEFINE_MEMBER(352, const ItemKind3, item_kind3);
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,15 @@
|
||||||
#include "ParamID.h"
|
#include "ParamID.h"
|
||||||
#include "MoverProperty.h"
|
#include "MoverProperty.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
template <class T, std::size_t N>
|
||||||
|
constexpr std::size_t size(const T (&array)[N]) noexcept
|
||||||
|
{
|
||||||
|
return N;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
namespace flyff {
|
namespace flyff {
|
||||||
namespace raw {
|
namespace raw {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
@ -30,6 +39,8 @@ namespace flyff {
|
||||||
extern u32 w2c_f411(u32);
|
extern u32 w2c_f411(u32);
|
||||||
// w2c_f2454: CCooltimeMgr::CanUse(uint64_t* timers, ItemProperty* prop);
|
// w2c_f2454: CCooltimeMgr::CanUse(uint64_t* timers, ItemProperty* prop);
|
||||||
extern u32 w2c_f2466(u32, u32);
|
extern u32 w2c_f2466(u32, u32);
|
||||||
|
// CObj::IsRangeObj()
|
||||||
|
extern u32 w2c_f512(u32 w2c_p0, u32 w2c_p1, f32 w2c_p2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -163,6 +174,8 @@ namespace flyff {
|
||||||
DEFINE_MEMBER(1840, int, hitpoints);
|
DEFINE_MEMBER(1840, int, hitpoints);
|
||||||
|
|
||||||
DEFINE_MEMBER(1848, int, is_grounded);
|
DEFINE_MEMBER(1848, int, is_grounded);
|
||||||
|
|
||||||
|
DEFINE_MEMBER(1884, float, arrival_range);
|
||||||
DEFINE_MEMBER(1888, const float, speed_factor);
|
DEFINE_MEMBER(1888, const float, speed_factor);
|
||||||
|
|
||||||
DEFINE_MEMBER(1804, uint32_t, object_state);
|
DEFINE_MEMBER(1804, uint32_t, object_state);
|
||||||
|
|
@ -206,7 +219,7 @@ namespace flyff {
|
||||||
|
|
||||||
bool is_in_combat(uint32_t millis = 10000) const;
|
bool is_in_combat(uint32_t millis = 10000) const;
|
||||||
|
|
||||||
uint32_t get_param(ParamID index, uint32_t base) const {
|
uint32_t get_param(ParamID index, uint32_t base = 0) const {
|
||||||
Parameter changeParam = get_change_param(index);
|
Parameter changeParam = get_change_param(index);
|
||||||
if (changeParam != 0x7FFFFFFF)
|
if (changeParam != 0x7FFFFFFF)
|
||||||
return changeParam;
|
return changeParam;
|
||||||
|
|
@ -234,7 +247,7 @@ namespace flyff {
|
||||||
return raw::w2c_f411(kMemory.to_inside(this));
|
return raw::w2c_f411(kMemory.to_inside(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
flyff::Pointer<flyff::ItemProperty> get_equipped_item(const flyff::Part &part) {
|
flyff::Pointer<flyff::ItemProperty> get_equipped_item(const flyff::Part &part) const {
|
||||||
using Fn = FunctionPointer<u32, u32, u32>;
|
using Fn = FunctionPointer<u32, u32, u32>;
|
||||||
const auto &fn = fugg::function_ref<Fn>(vtable->get_active_hand_item_prop);
|
const auto &fn = fugg::function_ref<Fn>(vtable->get_active_hand_item_prop);
|
||||||
|
|
||||||
|
|
@ -281,6 +294,32 @@ namespace flyff {
|
||||||
return fn(kMemory.to_inside(this), 0, 0);
|
return fn(kMemory.to_inside(this), 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float get_attack_range(const AttackRange& range) const {
|
||||||
|
static const float attack_ranges[] = {
|
||||||
|
2, 3, 4, 10, 15, 6, 18
|
||||||
|
};
|
||||||
|
|
||||||
|
float attack_range = 0.0f;
|
||||||
|
|
||||||
|
auto attack_range_index = static_cast<unsigned>(range) - 1;
|
||||||
|
if(attack_range_index < std::size(attack_ranges)) {
|
||||||
|
attack_range = attack_ranges[attack_range_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is_fly() && attack_range <= 3.0) {
|
||||||
|
attack_range = 3.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto nTmpATR = get_param(ParamID::DstHawkEye);
|
||||||
|
|
||||||
|
return attack_range * (nTmpATR / 100.0 + 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t is_object_in_range(const flyff::Pointer<Mover>& other, float range) {
|
||||||
|
auto self = flyff::Pointer<Mover>(this);
|
||||||
|
|
||||||
|
return raw::w2c_f512(static_cast<u32>(self), static_cast<u32>(other), range);
|
||||||
|
}
|
||||||
|
|
||||||
// int get_max_hp() const {
|
// int get_max_hp() const {
|
||||||
// return raw::w2c_f410(kMemory.to_inside(this));
|
// return raw::w2c_f410(kMemory.to_inside(this));
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ namespace flyff {
|
||||||
Stamina,
|
Stamina,
|
||||||
|
|
||||||
Speed = 4,
|
Speed = 4,
|
||||||
|
// DST_HAWKEYE_RATE: Increased attack range modifier.
|
||||||
|
DstHawkEye = 8,
|
||||||
// UnknownSpeed = 9,
|
// UnknownSpeed = 9,
|
||||||
|
|
||||||
AdditionalDamage = 35,
|
AdditionalDamage = 35,
|
||||||
|
|
@ -22,8 +24,30 @@ namespace flyff {
|
||||||
MaxHitPoint = 44,
|
MaxHitPoint = 44,
|
||||||
// DST_HP_MAX_RATE
|
// DST_HP_MAX_RATE
|
||||||
MaxHitPointScaling = 53,
|
MaxHitPointScaling = 53,
|
||||||
|
|
||||||
|
// Max = 82,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static std::ostream &operator<<(std::ostream &os, const ParamID &type) {
|
||||||
|
switch (type) {
|
||||||
|
case ParamID::Strength: os << "Strength"; break;
|
||||||
|
case ParamID::Dexterity: os << "Dexterity"; break;
|
||||||
|
case ParamID::Intelligence: os << "Intelligence"; break;
|
||||||
|
case ParamID::Stamina: os << "Stamina"; break;
|
||||||
|
|
||||||
|
case ParamID::Speed: os << "Speed"; break;
|
||||||
|
|
||||||
|
case ParamID::AdditionalDamage: os << "AdditionalDamage"; break;
|
||||||
|
|
||||||
|
case ParamID::MaxHitPoint: os << "MaxHitPoint"; break;
|
||||||
|
case ParamID::MaxHitPointScaling: os << "MaxHitPointScaling"; break;
|
||||||
|
|
||||||
|
default: os << "ParamID(" << static_cast<unsigned>(type) << ")";
|
||||||
|
}
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -753,7 +753,7 @@ static void w2c_f508(u32);
|
||||||
static u32 w2c_f509(u32);
|
static u32 w2c_f509(u32);
|
||||||
static void w2c_f510(u32, u32);
|
static void w2c_f510(u32, u32);
|
||||||
static u32 w2c_f511(u32);
|
static u32 w2c_f511(u32);
|
||||||
static u32 w2c_f512(u32, u32, f32);
|
u32 w2c_f512(u32, u32, f32);
|
||||||
static u32 w2c_f513(u32);
|
static u32 w2c_f513(u32);
|
||||||
static void w2c_f514(u32);
|
static void w2c_f514(u32);
|
||||||
u32 w2c_f515(u32, u32);
|
u32 w2c_f515(u32, u32);
|
||||||
|
|
@ -142263,7 +142263,7 @@ static u32 w2c_f511(u32 w2c_p0) {
|
||||||
return w2c_i0;
|
return w2c_i0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 w2c_f512(u32 w2c_p0, u32 w2c_p1, f32 w2c_p2) {
|
u32 w2c_f512(u32 w2c_p0, u32 w2c_p1, f32 w2c_p2) {
|
||||||
u32 w2c_l3 = 0, w2c_l4 = 0;
|
u32 w2c_l3 = 0, w2c_l4 = 0;
|
||||||
f32 w2c_l5 = 0;
|
f32 w2c_l5 = 0;
|
||||||
FUNC_PROLOGUE;
|
FUNC_PROLOGUE;
|
||||||
|
|
|
||||||
|
|
@ -145,6 +145,10 @@ namespace fugg {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::send_correction(const double &speed) const {
|
||||||
|
send_motion_packet(0x18, *reinterpret_cast<const unsigned long long *>(&speed));
|
||||||
|
}
|
||||||
|
|
||||||
void Client::send_chat_message(const std::string &message) const {
|
void Client::send_chat_message(const std::string &message) const {
|
||||||
std::vector<uint8_t> packet;
|
std::vector<uint8_t> packet;
|
||||||
// Message length
|
// Message length
|
||||||
|
|
@ -172,6 +176,7 @@ namespace fugg {
|
||||||
#include <emscripten/html5.h>
|
#include <emscripten/html5.h>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
|
||||||
flyff::Pointer<flyff::Mover::Buff>
|
flyff::Pointer<flyff::Mover::Buff>
|
||||||
|
|
@ -477,7 +482,10 @@ flyff::MoverID find_closest_target() {
|
||||||
|
|
||||||
if (mover->type == flyff::ObjectType::Mover &&
|
if (mover->type == flyff::ObjectType::Mover &&
|
||||||
current->hash != neuz.player_object_id &&
|
current->hash != neuz.player_object_id &&
|
||||||
|
// Should not be in dead state.
|
||||||
!mover->is_dead() &&
|
!mover->is_dead() &&
|
||||||
|
// Only attack enemies that are not attacking someone else.
|
||||||
|
mover->enemies->empty() &&
|
||||||
// Only attack ground mobs.
|
// Only attack ground mobs.
|
||||||
mover->is_grounded &&
|
mover->is_grounded &&
|
||||||
// Only attack same mobs.
|
// Only attack same mobs.
|
||||||
|
|
@ -542,19 +550,58 @@ flyff::MoverID find_next_item() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void interact(flyff::MoverID id, uint32_t action) {
|
void pickup_target(flyff::MoverID id, uint32_t action) {
|
||||||
const auto &client = fugg::Client::instance();
|
const auto &client = fugg::Client::instance();
|
||||||
|
|
||||||
if (!client.player)
|
if (!client.player)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (client.player->selected_target != id) {
|
||||||
client.player->selected_target = id;
|
client.player->selected_target = id;
|
||||||
client.send_set_target(id);
|
client.send_set_target(id);
|
||||||
|
}
|
||||||
|
|
||||||
client.player->move_toward_target = id;
|
|
||||||
client.send_interact_target(action);
|
client.send_interact_target(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void attack_target(flyff::MoverID id) {
|
||||||
|
const auto &client = fugg::Client::instance();
|
||||||
|
assert(client.player);
|
||||||
|
|
||||||
|
const auto& target = client.get_mover(id);
|
||||||
|
assert(target);
|
||||||
|
|
||||||
|
if (client.player->selected_target != id) {
|
||||||
|
client.player->selected_target = id;
|
||||||
|
client.send_set_target(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client.player->attack_target != id) {
|
||||||
|
auto item = client.player->get_equipped_item(flyff::Part::MainHand);
|
||||||
|
assert(item);
|
||||||
|
|
||||||
|
auto range = client.player->get_attack_range(item->attack_range);
|
||||||
|
auto result = client.player->is_object_in_range(target, range);
|
||||||
|
|
||||||
|
client.show_message("Range=" + std::to_string(range) + ", result=" + std::to_string(result));
|
||||||
|
|
||||||
|
if(result == 0) {
|
||||||
|
client.player->move_toward_target = id;
|
||||||
|
client.player->arrival_range = range;
|
||||||
|
}
|
||||||
|
|
||||||
|
client.player->attack_target = id;
|
||||||
|
client.send_interact_target(1);
|
||||||
|
|
||||||
|
// Maybe Wand too...
|
||||||
|
if(item->item_kind3 == flyff::ItemKind3::Bow) {
|
||||||
|
// Release the 'charged' shot immediatly.
|
||||||
|
client.send_motion_packet(0x15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
flyff::MoverID current_target = 0;
|
flyff::MoverID current_target = 0;
|
||||||
flyff::MoverID current_pickup_item = 0;
|
flyff::MoverID current_pickup_item = 0;
|
||||||
|
|
||||||
|
|
@ -619,7 +666,7 @@ void attacker_script() {
|
||||||
const auto &item_property = items[i].property;
|
const auto &item_property = items[i].property;
|
||||||
if (item_property &&
|
if (item_property &&
|
||||||
player->can_use_item(item_property) &&
|
player->can_use_item(item_property) &&
|
||||||
item_property->item_kind3 == flyff::ItemKind3::HealthPill) {
|
item_property->item_kind3 == flyff::ItemKind3::Pill) {
|
||||||
auto hp = client.player->get_hp();
|
auto hp = client.player->get_hp();
|
||||||
auto max_hp = client.player->get_max_hp();
|
auto max_hp = client.player->get_max_hp();
|
||||||
// How much HP is left over after healing with this item.
|
// How much HP is left over after healing with this item.
|
||||||
|
|
@ -633,7 +680,7 @@ void attacker_script() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pill_item) {
|
if (pill_item) {
|
||||||
std::string str = "Eating ";
|
std::string str = "Eating ";
|
||||||
str.append(neuz.get_text(pill_item->property->name));
|
str.append(neuz.get_text(pill_item->property->name));
|
||||||
str.append(" because food item was not ready.");
|
str.append(" because food item was not ready.");
|
||||||
|
|
@ -645,11 +692,27 @@ void attacker_script() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// Check if my current target is being attacked by another player.
|
||||||
|
{
|
||||||
|
auto monster = neuz.get_mover(current_target);
|
||||||
|
if (monster && !monster->enemies->empty()) {
|
||||||
|
auto is_player_monster_enemy =
|
||||||
|
std::find(monster->enemies.begin(), monster->enemies.end(), client.player->object_id) != nullptr;
|
||||||
|
// If the player is not in the list of enemies, we can not attack the monster.
|
||||||
|
if (!is_player_monster_enemy) {
|
||||||
|
client.show_message("Uh oh, you are being killstealed.", {0xFF, 0, 0});
|
||||||
|
|
||||||
if (neuz.player->get_move_state() == flyff::Object::MoveState::Stand &&
|
current_target = 0;
|
||||||
|
neuz.player->selected_target = 0;
|
||||||
|
client.send_clear_target();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((neuz.player->get_move_state() == flyff::Object::MoveState::Stand ||
|
||||||
|
neuz.player->get_move_state() == flyff::Object::MoveState::PickUp) &&
|
||||||
!neuz.player->is_attacking()) {
|
!neuz.player->is_attacking()) {
|
||||||
|
|
||||||
|
|
||||||
// Check buffs.
|
// Check buffs.
|
||||||
static constexpr flyff::SkillID buffs_to_check[] = {
|
static constexpr flyff::SkillID buffs_to_check[] = {
|
||||||
// flyff::SkillID::MentalSign,
|
// flyff::SkillID::MentalSign,
|
||||||
|
|
@ -722,10 +785,10 @@ void attacker_script() {
|
||||||
|
|
||||||
if (item && !item->is_despawned && neuz.player->move_toward_target == 0) {
|
if (item && !item->is_despawned && neuz.player->move_toward_target == 0) {
|
||||||
// Pickup
|
// Pickup
|
||||||
interact(item->object_id, 1);
|
pickup_target(item->object_id, 1);
|
||||||
} else if (monster && !monster->is_dead() && neuz.player->move_toward_target == 0) {
|
} else if (monster && !monster->is_dead() && neuz.player->attack_target == 0) {
|
||||||
// Attack
|
// Attack
|
||||||
interact(monster->object_id, 1);
|
attack_target(monster->object_id);
|
||||||
// neuz.player->attack_target = monster->object_id;
|
// neuz.player->attack_target = monster->object_id;
|
||||||
} else if ((!item || item->is_despawned) &&
|
} else if ((!item || item->is_despawned) &&
|
||||||
(!monster || monster->is_dead())) {
|
(!monster || monster->is_dead())) {
|
||||||
|
|
@ -741,14 +804,14 @@ void attacker_script() {
|
||||||
str.append(" because it is my enemy.");
|
str.append(" because it is my enemy.");
|
||||||
|
|
||||||
current_target = id;
|
current_target = id;
|
||||||
interact(id, 1);
|
attack_target(id);
|
||||||
|
|
||||||
neuz.show_message(str);
|
neuz.show_message(str);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Only pickup if player has no pickup pet spawned.
|
// Only pickup if player has no pickup pet spawned.
|
||||||
if(client.player->pickup_pet_inventory_index == -1) {
|
if (client.player->pickup_pet_inventory_index == -1) {
|
||||||
// No item target and no attack target
|
// No item target and no attack target
|
||||||
current_pickup_item = find_next_item();
|
current_pickup_item = find_next_item();
|
||||||
item = neuz.get_mover(current_pickup_item);
|
item = neuz.get_mover(current_pickup_item);
|
||||||
|
|
@ -760,7 +823,7 @@ void attacker_script() {
|
||||||
std::string str = "Picking up ";
|
std::string str = "Picking up ";
|
||||||
str.append(neuz.get_text(prop->name));
|
str.append(neuz.get_text(prop->name));
|
||||||
|
|
||||||
interact(item->object_id, 1);
|
pickup_target(item->object_id, 1);
|
||||||
|
|
||||||
neuz.show_message(str);
|
neuz.show_message(str);
|
||||||
return;
|
return;
|
||||||
|
|
@ -773,7 +836,7 @@ void attacker_script() {
|
||||||
std::string str = "Attacking ";
|
std::string str = "Attacking ";
|
||||||
str.append(monster->name);
|
str.append(monster->name);
|
||||||
|
|
||||||
interact(current_target, 1);
|
attack_target(current_target);
|
||||||
|
|
||||||
neuz.show_message(str);
|
neuz.show_message(str);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -919,7 +982,13 @@ void after_main_loop() {
|
||||||
// std::cout << "Speed: " << client.player->get_speed() << std::endl;
|
// std::cout << "Speed: " << client.player->get_speed() << std::endl;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
if (client.player) {
|
||||||
|
auto monster = client.get_mover(client.player->selected_target);
|
||||||
|
|
||||||
|
if (monster) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (script) {
|
switch (script) {
|
||||||
case ScriptType::Attacker:
|
case ScriptType::Attacker:
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,8 @@ namespace fugg {
|
||||||
void send_use_skill(const flyff::SkillID &id, unsigned long long unknown = -1) const;
|
void send_use_skill(const flyff::SkillID &id, unsigned long long unknown = -1) const;
|
||||||
void send_follow_target(const unsigned long long &id) const;
|
void send_follow_target(const unsigned long long &id) const;
|
||||||
|
|
||||||
|
void send_correction(const double& speed) const;
|
||||||
|
|
||||||
void send_move_to(const double &x, const double &y, const double &z) const;
|
void send_move_to(const double &x, const double &y, const double &z) const;
|
||||||
void send_chat_message(const std::string &message) const;
|
void send_chat_message(const std::string &message) const;
|
||||||
|
|
||||||
|
|
|
||||||
Reference in New Issue