Added mana and fatigue point recovery (along with get_mp(), get_fp(), get_max_mp(), get_max_fp())
This commit is contained in:
parent
1c9001f582
commit
af66bfc82f
|
|
@ -84,7 +84,9 @@ namespace flyff {
|
|||
Necklace = 501,
|
||||
Ring = 502,
|
||||
|
||||
|
||||
Refresher = 1400,
|
||||
VitalDrink = 1401,
|
||||
Food = 1402,
|
||||
Pill = 1404
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ namespace flyff {
|
|||
DEFINE_MEMBER(0, const flyff::String, model);
|
||||
DEFINE_MEMBER(12, const uint32_t, id);
|
||||
|
||||
DEFINE_MEMBER(60, const uint32_t, heal_hp);
|
||||
DEFINE_MEMBER(60, const uint32_t, recovery);
|
||||
DEFINE_MEMBER(96, const uint32_t, effective_up_to);
|
||||
|
||||
// Has to be bigger that 0 to be considered for cooldown.
|
||||
DEFINE_MEMBER(112, const int32_t, cooldown_time);
|
||||
|
|
@ -52,6 +53,32 @@ namespace flyff {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool is_refresher() const {
|
||||
static const uint32_t RECOVERY_SUB_CATEGORY_START = 1400;
|
||||
|
||||
if (item_kind2 == ItemKind2::Recovery) {
|
||||
const uint32_t cd = static_cast<uint32_t>(item_kind3) - RECOVERY_SUB_CATEGORY_START;
|
||||
if (cd < 5) {
|
||||
return RECOVERY_COOLDOWN_INDEX[cd] == COOLDOWN_REFRESHER;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_vitaldrink() const {
|
||||
static const uint32_t RECOVERY_SUB_CATEGORY_START = 1400;
|
||||
|
||||
if (item_kind2 == ItemKind2::Recovery) {
|
||||
const uint32_t cd = static_cast<uint32_t>(item_kind3) - RECOVERY_SUB_CATEGORY_START;
|
||||
if (cd < 5) {
|
||||
return RECOVERY_COOLDOWN_INDEX[cd] == COOLDOWN_VITALDRINK;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_quest() const { return item_kind2 == ItemKind2::Quest; }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ namespace flyff {
|
|||
|
||||
DEFINE_MEMBER(144, const u32, get_max_origin_hp);
|
||||
DEFINE_MEMBER(148, const u32, get_max_origin_mp);
|
||||
DEFINE_MEMBER(152, const u32, get_max_origin_fp);
|
||||
|
||||
const MinimumSize<220> _size;
|
||||
};
|
||||
|
|
@ -154,6 +155,7 @@ namespace flyff {
|
|||
DEFINE_MEMBER(880, const uint32_t, locked_inventory_slots);
|
||||
|
||||
DEFINE_MEMBER(904, uint32_t, if_not_null_needsattackitem);
|
||||
DEFINE_MEMBER(908, uint32_t, fatiguepoints);
|
||||
|
||||
DEFINE_MEMBER(920, ParameterValue, adjusted_parameters[MAX_PARAM]);
|
||||
DEFINE_MEMBER(1248, ParameterValue, changed_parameters[MAX_PARAM]);
|
||||
|
|
@ -183,6 +185,7 @@ namespace flyff {
|
|||
DEFINE_MEMBER(1820, uint32_t, server_tick);
|
||||
|
||||
DEFINE_MEMBER(1840, int, hitpoints);
|
||||
DEFINE_MEMBER(1844, int, manapoints);
|
||||
|
||||
DEFINE_MEMBER(1848, int, is_grounded);
|
||||
|
||||
|
|
@ -247,9 +250,6 @@ namespace flyff {
|
|||
|
||||
ParameterValue get_change_param(ParamID index) const;
|
||||
|
||||
uint32_t get_hp() const {
|
||||
return raw::get_hitpoint(kMemory.to_inside(this));
|
||||
}
|
||||
|
||||
flyff::Pointer<flyff::ItemProperty> get_equipped_item(const flyff::Part &part) const {
|
||||
using Fn = FunctionPointer<u32, u32, u32>;
|
||||
|
|
@ -273,6 +273,18 @@ namespace flyff {
|
|||
return src_speed <= 0 ? 0 : src_speed;
|
||||
}
|
||||
|
||||
uint32_t get_hp() const {
|
||||
return hitpoints ^ adj_param;
|
||||
}
|
||||
|
||||
uint32_t get_mp() const {
|
||||
return manapoints ^ adj_param;
|
||||
}
|
||||
|
||||
uint32_t get_fp() const {
|
||||
return fatiguepoints;
|
||||
}
|
||||
|
||||
uint32_t get_max_hp() const {
|
||||
float factor = 1.0f;
|
||||
auto result = get_param(ParamID::MaxHitPoint, get_max_origin_hp());
|
||||
|
|
@ -284,6 +296,28 @@ namespace flyff {
|
|||
return result;
|
||||
}
|
||||
|
||||
uint32_t get_max_mp() const {
|
||||
float factor = 1.0f;
|
||||
auto result = get_param(ParamID::MaxManaPoint, get_max_origin_mp());
|
||||
auto percent = get_param(ParamID::MaxManaPointScaling, 0);
|
||||
|
||||
factor += static_cast<float>(percent) / 100.f;
|
||||
result = static_cast<float>(result) * factor;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t get_max_fp() const {
|
||||
float factor = 1.0f;
|
||||
auto result = get_param(ParamID::MaxFatiguePoint, get_max_origin_fp());
|
||||
auto percent = get_param(ParamID::MaxFatiguePointScaling, 0);
|
||||
|
||||
factor += static_cast<float>(percent) / 100.f;
|
||||
result = static_cast<float>(result) * factor;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t get_hp_percent(int percent = 100) const {
|
||||
auto max = get_max_hp();
|
||||
if (max == 0) return 0;
|
||||
|
|
@ -291,6 +325,20 @@ namespace flyff {
|
|||
return get_hp() * percent / max;
|
||||
}
|
||||
|
||||
uint32_t get_mp_percent(int percent = 100) const {
|
||||
auto max = get_max_mp();
|
||||
if (max == 0) return 0;
|
||||
|
||||
return get_mp() * percent / max;
|
||||
}
|
||||
|
||||
uint32_t get_fp_percent(int percent = 100) const {
|
||||
auto max = get_max_fp();
|
||||
if (max == 0) return 0;
|
||||
|
||||
return get_fp() * percent / max;
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
@ -298,6 +346,20 @@ namespace flyff {
|
|||
return fn(kMemory.to_inside(this), 0, 0);
|
||||
}
|
||||
|
||||
uint32_t get_max_origin_mp() const {
|
||||
using Fn = FunctionPointer<u32, u32, u32, u32>;
|
||||
const auto &fn = fugg::function_ref<Fn>(vtable->get_max_origin_mp);
|
||||
|
||||
return fn(kMemory.to_inside(this), 0, 0);
|
||||
}
|
||||
|
||||
uint32_t get_max_origin_fp() const {
|
||||
using Fn = FunctionPointer<u32, u32, u32, u32>;
|
||||
const auto &fn = fugg::function_ref<Fn>(vtable->get_max_origin_fp);
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -22,8 +22,15 @@ namespace flyff {
|
|||
AdditionalDamage = 35,
|
||||
// DST_HP_MAX
|
||||
MaxHitPoint = 44,
|
||||
// DST_MP_MAX
|
||||
MaxManaPoint,
|
||||
// DST_FP_MAX
|
||||
MaxFatiguePoint,
|
||||
|
||||
// DST_HP_MAX_RATE
|
||||
MaxHitPointScaling = 53,
|
||||
MaxManaPointScaling,
|
||||
MaxFatiguePointScaling,
|
||||
|
||||
// Max = 82,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,8 +4,13 @@
|
|||
|
||||
namespace flyff {
|
||||
enum class SkillID : uint32_t {
|
||||
// Assist skills
|
||||
|
||||
/* Mercenary */
|
||||
SwordMastery = 7,
|
||||
Protect = 9,
|
||||
BlazingSword = 108,
|
||||
EmpowerWeapon = 111,
|
||||
HeartOfFury = 404,
|
||||
/* Assist */
|
||||
Haste = 20,
|
||||
Heal = 44,
|
||||
Resurrection = 45,
|
||||
|
|
@ -27,7 +32,7 @@ namespace flyff {
|
|||
|
||||
|
||||
static std::ostream &operator<<(std::ostream &os, const SkillID &type) {
|
||||
os << static_cast<uint32_t>(type);
|
||||
os << "SkillID(" << static_cast<uint32_t>(type) << ")";
|
||||
return os;
|
||||
}
|
||||
}; // namespace flyff
|
||||
|
|
@ -472,6 +472,15 @@ void on_keyup_hook(int event_type, const EmscriptenKeyboardEvent *event, void *u
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Player has the following " << client.player->skills->size() << " skills" << std::endl;
|
||||
for(const auto& skill : client.player->skills) {
|
||||
const auto& property = fugg::Client::get_skill_property(skill.id);
|
||||
if(property) {
|
||||
std::cout << client.get_text(property->name) << " ";
|
||||
}
|
||||
std::cout << "(" << skill.id << ") at level " << skill.level << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -642,7 +651,7 @@ void attacker_script() {
|
|||
auto hp = client.player->get_hp();
|
||||
auto max_hp = client.player->get_max_hp();
|
||||
// How much HP is left over after healing with this item.
|
||||
int32_t difference = max_hp - (hp + item_property->heal_hp);
|
||||
int32_t difference = max_hp - (hp + item_property->recovery);
|
||||
|
||||
if (difference >= 0 && std::abs(difference) < std::abs(smallest_difference)) {
|
||||
food_item = flyff::Pointer<flyff::InventoryItem>(&items[i]);
|
||||
|
|
@ -673,7 +682,7 @@ void attacker_script() {
|
|||
auto hp = client.player->get_hp();
|
||||
auto max_hp = client.player->get_max_hp();
|
||||
// How much HP is left over after healing with this item.
|
||||
int32_t difference = max_hp - (hp + item_property->heal_hp);
|
||||
int32_t difference = max_hp - (hp + item_property->recovery);
|
||||
|
||||
if (difference >= 0 && std::abs(difference) < std::abs(smallest_difference)) {
|
||||
pill_item = flyff::Pointer<flyff::InventoryItem>(&items[i]);
|
||||
|
|
@ -688,12 +697,76 @@ void attacker_script() {
|
|||
str.append(neuz.get_text(pill_item->property->name));
|
||||
str.append(" because food item was not ready.");
|
||||
|
||||
neuz.show_message(str);
|
||||
neuz.show_message(str, {0x7F, 0, 0});
|
||||
|
||||
client.send_use_item_in_inventory(pill_item->index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (neuz.player->get_mp_percent() != 100) {
|
||||
auto mana_item = flyff::Pointer<flyff::InventoryItem>(nullptr);
|
||||
auto items = player->inventory.begin();
|
||||
int32_t smallest_difference = std::numeric_limits<int32_t>::max();
|
||||
for (auto i = 0; i < player->get_inventory_slots(); i++) {
|
||||
const auto &item_property = items[i].property;
|
||||
if (item_property &&
|
||||
player->can_use_item(item_property) &&
|
||||
item_property->is_refresher()) {
|
||||
auto mp = client.player->get_mp();
|
||||
auto max_mp = client.player->get_max_mp();
|
||||
// How much HP is left over after healing with this item.
|
||||
int32_t difference = max_mp - (mp + item_property->recovery);
|
||||
|
||||
if (difference >= 0 && std::abs(difference) < std::abs(smallest_difference)) {
|
||||
mana_item = flyff::Pointer<flyff::InventoryItem>(&items[i]);
|
||||
smallest_difference = difference;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mana_item) {
|
||||
std::string str = "Using ";
|
||||
str.append(neuz.get_text(mana_item->property->name));
|
||||
|
||||
neuz.show_message(str, {0, 0, 0x7F});
|
||||
|
||||
client.send_use_item_in_inventory(mana_item->index);
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Player has " << neuz.player->get_mp() << " / " << neuz.player->get_max_mp() << " MP" << std::endl;
|
||||
std::cout << "Player has " << neuz.player->get_fp() << " / " << neuz.player->get_max_fp() << " FP" << std::endl;
|
||||
|
||||
if (neuz.player->get_fp_percent() != 100) {
|
||||
auto fatigue_item = flyff::Pointer<flyff::InventoryItem>(nullptr);
|
||||
auto items = player->inventory.begin();
|
||||
int32_t smallest_difference = std::numeric_limits<int32_t>::max();
|
||||
for (auto i = 0; i < player->get_inventory_slots(); i++) {
|
||||
const auto &item_property = items[i].property;
|
||||
if (item_property &&
|
||||
player->can_use_item(item_property) &&
|
||||
item_property->is_vitaldrink()) {
|
||||
auto fp = client.player->get_fp();
|
||||
auto max_fp = client.player->get_max_fp();
|
||||
// How much HP is left over after healing with this item.
|
||||
int32_t difference = max_fp - (fp + item_property->recovery);
|
||||
|
||||
if (difference >= 0 && std::abs(difference) < std::abs(smallest_difference)) {
|
||||
fatigue_item = flyff::Pointer<flyff::InventoryItem>(&items[i]);
|
||||
smallest_difference = difference;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fatigue_item) {
|
||||
std::string str = "Drinking ";
|
||||
str.append(neuz.get_text(fatigue_item->property->name));
|
||||
|
||||
neuz.show_message(str, {0, 0x7F, 0});
|
||||
|
||||
client.send_use_item_in_inventory(fatigue_item->index);
|
||||
}
|
||||
}
|
||||
// Check if my current target is being attacked by another player.
|
||||
{
|
||||
|
|
@ -701,7 +774,9 @@ void attacker_script() {
|
|||
if (monster && !monster->enemies->empty()) {
|
||||
auto is_player_monster_enemy =
|
||||
std::find_if(monster->enemies.begin(), monster->enemies.end(),
|
||||
[&client](const flyff::Mover::HitInfo &x) { return x.object_id == client.player->object_id; }) !=
|
||||
[&client](const flyff::Mover::HitInfo &x) {
|
||||
return x.object_id == client.player->object_id;
|
||||
}) !=
|
||||
monster->enemies.end();
|
||||
// If the player is not in the list of enemies, we can not attack the monster.
|
||||
if (!is_player_monster_enemy) {
|
||||
|
|
@ -788,7 +863,16 @@ void attacker_script() {
|
|||
client.send_use_skill(flyff::SkillID::Asmodeus);
|
||||
return;
|
||||
}
|
||||
// }
|
||||
} else if(neuz.player->get_job() == flyff::JobID::Knight) {
|
||||
const auto &off_hand = player->get_equipped_item(flyff::Part::Shield);
|
||||
|
||||
if (off_hand && off_hand->item_kind3 == flyff::ItemKind3::Shield) {
|
||||
// Only check for the buff if player is wearing a shield.
|
||||
if (!check_rebuff(neuz.player, neuz.player, {flyff::SkillID::HeartOfFury}).empty()) {
|
||||
client.send_use_skill(flyff::SkillID::HeartOfFury);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (item && !item->is_despawned && neuz.player->move_toward_target == 0) {
|
||||
|
|
|
|||
Reference in New Issue