aozhiwei 6ce1e21da3 1
2023-04-13 16:18:09 +08:00

990 lines
28 KiB
C++

#include "precompile.h"
#include "ability.h"
#include "buff.h"
#include "creature.h"
#include "mt/Equip.h"
#include "mt/Buff.h"
struct AttrAbsPtr
{
struct AttrAbs* data;
AttrAbsPtr(AttrAbs* data) { this->data = data; };
};
struct AttrAbs
{
list_head entry;
int attr_id;
float value;
std::shared_ptr<AttrAbsPtr> ptr;
AttrAbs(int attr_id, float value)
{
this->attr_id = attr_id;
this->value = value;
INIT_LIST_HEAD(&entry);
ptr = std::make_shared<AttrAbsPtr>(this);
}
};
struct AttrRatePtr
{
struct AttrRate* data;
AttrRatePtr(AttrRate* data) { this->data = data; };
};
struct AttrRate
{
list_head entry;
int attr_id;
float value;
std::shared_ptr<AttrRatePtr> ptr;
AttrRate(int attr_id, float value)
{
this->attr_id = attr_id;
this->value = value;
INIT_LIST_HEAD(&entry);
ptr = std::make_shared<AttrRatePtr>(this);
}
};
struct AttrAdditionPtr
{
struct AttrAddition* data;
AttrAdditionPtr(AttrAddition* data) { this->data = data; };
};
struct AttrAddition
{
list_head entry;
int attr_id;
float value;
std::shared_ptr<AttrAdditionPtr> ptr;
AttrAddition(int attr_id, float value)
{
this->attr_id = attr_id;
this->value = value;
INIT_LIST_HEAD(&entry);
ptr = std::make_shared<AttrAdditionPtr>(this);
}
};
struct AttrRuducePtr
{
struct AttrRuduce* data;
AttrRuducePtr(AttrRuduce* data) { this->data = data; };
};
struct AttrRuduce
{
list_head entry;
int attr_id;
float value;
std::shared_ptr<AttrRuducePtr> ptr;
AttrRuduce(int attr_id, float value)
{
this->attr_id = attr_id;
this->value = value;
INIT_LIST_HEAD(&entry);
ptr = std::make_shared<AttrRuducePtr>(this);
}
};
struct AttrDirectPtr
{
struct AttrDirect* data;
AttrDirectPtr(AttrDirect* data) { this->data = data; };
};
struct AttrDirect
{
list_head entry;
int attr_id;
float value;
std::shared_ptr<AttrDirectPtr> ptr;
AttrDirect(int attr_id, float value)
{
this->attr_id = attr_id;
this->value = value;
INIT_LIST_HEAD(&entry);
ptr = std::make_shared<AttrDirectPtr>(this);
}
};
Ability::Ability(CreatureWeakPtr owner)
{
for (auto& tuple : attr_abs_) {
std::get<0>(tuple) = 0.0f;
INIT_LIST_HEAD(&std::get<1>(tuple));
}
for (auto& tuple : attr_rate_) {
std::get<0>(tuple) = 0.0f;
INIT_LIST_HEAD(&std::get<1>(tuple));
}
for (auto& tuple : attr_add_) {
std::get<0>(tuple) = 0.0f;
INIT_LIST_HEAD(&std::get<1>(tuple));
}
for (auto& tuple : attr_dec_) {
std::get<0>(tuple) = 0.0f;
INIT_LIST_HEAD(&std::get<1>(tuple));
}
for (auto& tuple : vattr_add_) {
std::get<0>(tuple) = 0.0f;
INIT_LIST_HEAD(&std::get<1>(tuple));
}
for (auto& tuple : vattr_dec_) {
std::get<0>(tuple) = 0.0f;
INIT_LIST_HEAD(&std::get<1>(tuple));
}
for (auto& tuple : attr_direct_) {
std::get<0>(tuple) = 0.0f;
INIT_LIST_HEAD(&std::get<1>(tuple));
}
}
void Ability::Clear()
{
for (auto& tuple : attr_abs_) {
std::get<0>(tuple) = 0.0f;
while (!list_empty(&std::get<1>(tuple))) {
AttrAbs* e = list_first_entry(&std::get<1>(tuple),
AttrAbs,
entry);
e->ptr->data = nullptr;
list_del_init(&e->entry);
delete e;
}
}
for (auto& tuple : attr_rate_) {
std::get<0>(tuple) = 0.0f;
while (!list_empty(&std::get<1>(tuple))) {
AttrRate* e = list_first_entry(&std::get<1>(tuple),
AttrRate,
entry);
e->ptr->data = nullptr;
list_del_init(&e->entry);
delete e;
}
}
for (auto& tuple : attr_add_) {
std::get<0>(tuple) = 0.0f;
while (!list_empty(&std::get<1>(tuple))) {
AttrAddition* e = list_first_entry(&std::get<1>(tuple),
AttrAddition,
entry);
e->ptr->data = nullptr;
list_del_init(&e->entry);
delete e;
}
}
for (auto& tuple : attr_dec_) {
std::get<0>(tuple) = 0.0f;
while (!list_empty(&std::get<1>(tuple))) {
AttrRuduce* e = list_first_entry(&std::get<1>(tuple),
AttrRuduce,
entry);
e->ptr->data = nullptr;
list_del_init(&e->entry);
delete e;
}
}
for (auto& tuple : vattr_add_) {
std::get<0>(tuple) = 0.0f;
while (!list_empty(&std::get<1>(tuple))) {
AttrAddition* e = list_first_entry(&std::get<1>(tuple),
AttrAddition,
entry);
e->ptr->data = nullptr;
list_del_init(&e->entry);
delete e;
}
}
for (auto& tuple : vattr_dec_) {
std::get<0>(tuple) = 0.0f;
while (!list_empty(&std::get<1>(tuple))) {
AttrRuduce* e = list_first_entry(&std::get<1>(tuple),
AttrRuduce,
entry);
e->ptr->data = nullptr;
list_del_init(&e->entry);
delete e;
}
}
for (auto& tuple : attr_direct_) {
std::get<0>(tuple) = 0.0f;
while (!list_empty(&std::get<1>(tuple))) {
AttrDirect* e = list_first_entry(&std::get<1>(tuple),
AttrDirect,
entry);
e->ptr->data = nullptr;
list_del_init(&e->entry);
delete e;
}
}
switch_times_ = {};
immune_tags_.clear();
}
void Ability::IncImmuneTimes(int tag)
{
auto itr = immune_tags_.find(tag);
if (itr != immune_tags_.end()) {
++itr->second;
} else {
immune_tags_[tag] = 1;
}
}
void Ability::DecImmuneTimes(int tag)
{
auto itr = immune_tags_.find(tag);
if (itr != immune_tags_.end()) {
--itr->second;
if (itr->second <= 0) {
immune_tags_.erase(itr);
}
}
}
bool Ability::CanImmune(int tag)
{
return immune_tags_.find(tag) != immune_tags_.end();
}
bool Ability::CanImmune(const std::set<int>& tags)
{
if (!immune_tags_.empty()) {
for (int tag : tags) {
if (CanImmune(tag)) {
return true;
}
}
}
return false;
}
AttrAbsHandle Ability::AddAttrAbs(int attr_id, float value)
{
if (IsValidHumanAttr(attr_id)) {
auto p = new AttrAbs(attr_id, value);
list_add_tail(&p->entry, &std::get<1>(attr_abs_[attr_id]));
RecalcAttrAbs(attr_id);
return p->ptr;
}
return AttrAbsHandle();
}
void Ability::RemoveAttrAbs(AttrAbsHandle handle)
{
if (!handle.expired()) {
auto p = handle.lock();
list_del_init(&p->data->entry);
RecalcAttrAbs(p->data->attr_id);
delete p->data;
}
}
AttrRateHandle Ability::AddAttrRate(int attr_id, float value)
{
if (IsValidHumanAttr(attr_id)) {
auto p = new AttrRate(attr_id, value);
list_add_tail(&p->entry, &std::get<1>(attr_rate_[attr_id]));
RecalcAttrRate(attr_id);
return p->ptr;
}
return AttrRateHandle();
}
void Ability::RemoveAttrRate(AttrRateHandle handle)
{
if (!handle.expired()) {
auto p = handle.lock();
list_del_init(&p->data->entry);
RecalcAttrRate(p->data->attr_id);
delete p->data;
}
}
void Ability::RecalcAttrAbs(int attr_id)
{
list_head* head = &std::get<1>(attr_abs_[attr_id]);
list_head* pos = nullptr;
list_head* next = nullptr;
float new_val = 0.0f;
list_for_each_safe(pos, next, head) {
AttrAbs* e = list_entry(pos,
AttrAbs,
entry);
new_val += e->value;
}
std::get<0>(attr_abs_[attr_id]) = new_val;
}
void Ability::RecalcAttrRate(int attr_id)
{
list_head* head = &std::get<1>(attr_rate_[attr_id]);
list_head* pos = nullptr;
list_head* next = nullptr;
float new_val = 0.0f;
list_for_each_safe(pos, next, head) {
AttrRate* e = list_entry(pos,
AttrRate,
entry);
new_val += e->value;
}
std::get<0>(attr_rate_[attr_id]) = new_val;
}
float Ability::GetAttrAbs(int attr_id)
{
if (IsValidHumanAttr(attr_id)) {
return std::get<0>(attr_abs_[attr_id]);
} else {
return 0.0f;
}
}
float Ability::GetAttrRate(int attr_id)
{
if (IsValidHumanAttr(attr_id)) {
return std::get<0>(attr_rate_[attr_id]);
} else {
return 0.0f;
}
}
AttrAdditionHandle Ability::AddAttrAddition(int attr_id, float rate)
{
if (IsValidHumanAttr(attr_id) ||
IsValidHumanVirtualAttr(attr_id)) {
auto p = new AttrAddition(attr_id, rate);
if (IsValidHumanAttr(attr_id)) {
list_add_tail(&p->entry, &std::get<1>(attr_add_[attr_id]));
} else {
list_add_tail(&p->entry, &std::get<1>(vattr_add_[attr_id - kHVAT_Begin]));
}
RecalcAttrAddition(attr_id);
return p->ptr;
}
return AttrAdditionHandle();
}
void Ability::RemoveAttrAddition(AttrAdditionHandle handle)
{
if (!handle.expired()) {
auto p = handle.lock();
list_del_init(&p->data->entry);
RecalcAttrAddition(p->data->attr_id);
delete p->data;
}
}
AttrRuduceHandle Ability::AddAttrRuduce(int attr_id, float rate)
{
if (IsValidHumanAttr(attr_id) ||
IsValidHumanVirtualAttr(attr_id)) {
auto p = new AttrRuduce(attr_id, rate);
if (IsValidHumanAttr(attr_id)) {
list_add_tail(&p->entry, &std::get<1>(attr_dec_[attr_id]));
} else {
list_add_tail(&p->entry, &std::get<1>(vattr_dec_[attr_id - kHVAT_Begin]));
}
RecalcAttrRuduce(attr_id);
return p->ptr;
}
return AttrRuduceHandle();
}
void Ability::RemoveAttrRuduce(AttrRuduceHandle handle)
{
if (!handle.expired()) {
auto p = handle.lock();
list_del_init(&p->data->entry);
RecalcAttrRuduce(p->data->attr_id);
delete p->data;
}
}
void Ability::RecalcAttrAddition(int attr_id)
{
list_head* head = nullptr;
if (IsValidHumanAttr(attr_id)) {
head = &std::get<1>(attr_add_[attr_id]);
} else if (IsValidHumanVirtualAttr(attr_id)) {
head = &std::get<1>(vattr_add_[attr_id - kHVAT_Begin]);
} else {
return;
}
list_head* pos = nullptr;
list_head* next = nullptr;
float new_val = 0.0f;
list_for_each_safe(pos, next, head) {
AttrAddition* e = list_entry(pos,
AttrAddition,
entry);
new_val += e->value;
}
if (IsValidHumanAttr(attr_id)) {
std::get<0>(attr_add_[attr_id]) = new_val;
} else if (IsValidHumanVirtualAttr(attr_id)) {
std::get<0>(vattr_add_[attr_id - kHVAT_Begin]) = new_val;
}
}
void Ability::RecalcAttrRuduce(int attr_id)
{
list_head* head = nullptr;
if (IsValidHumanAttr(attr_id)) {
head = &std::get<1>(attr_dec_[attr_id]);
} else if (IsValidHumanVirtualAttr(attr_id)) {
head = &std::get<1>(vattr_dec_[attr_id - kHVAT_Begin]);
} else {
return;
}
list_head* pos = nullptr;
list_head* next = nullptr;
bool inited = false;
float new_val = 0.0f;
list_for_each_safe(pos, next, head) {
AttrRuduce* e = list_entry(pos,
AttrRuduce,
entry);
switch (attr_id) {
case kHAT_Speed:
{
new_val = std::max(new_val, e->value);
}
break;
case kHVAT_Dmg:
{
if (inited) {
new_val *= 1.0f - e->value;
} else {
new_val = 1.0f - e->value;
inited = true;
}
}
break;
default:
{
new_val += e->value;
}
break;
}
}
if (IsValidHumanAttr(attr_id)) {
std::get<0>(attr_dec_[attr_id]) = new_val;
} else if (IsValidHumanVirtualAttr(attr_id)) {
std::get<0>(vattr_dec_[attr_id - kHVAT_Begin]) = new_val;
}
}
float Ability::GetAttrAddition(int attr_id)
{
if (IsValidHumanAttr(attr_id)) {
return std::get<0>(attr_add_[attr_id]);
} else if (IsValidHumanVirtualAttr(attr_id)) {
return std::get<0>(vattr_add_[attr_id - kHVAT_Begin]);
} else {
return 0.0f;
}
}
float Ability::GetAttrRuduce(int attr_id)
{
if (IsValidHumanAttr(attr_id)) {
return std::get<0>(attr_dec_[attr_id]);
} else if (IsValidHumanVirtualAttr(attr_id)) {
return std::get<0>(vattr_dec_[attr_id - kHVAT_Begin]);
} else {
return 0.0f;
}
}
void Ability::GMDelBaseAttr(int type, int attr_id, int idx)
{
if (IsValidHumanAttr(attr_id)) {
if (type == 1) {
list_head* head = &std::get<1>(attr_abs_[attr_id]);
list_head* pos = nullptr;
list_head* next = nullptr;
int i = 0;
list_for_each_safe(pos, next, head) {
if (idx == -1 || idx == i) {
AttrAbs* e = list_entry(pos,
AttrAbs,
entry);
list_del_init(&e->entry);
delete e;
if (idx > -1) {
break;
}
}
++i;
}
RecalcAttrAbs(attr_id);
} else if (type == 2) {
list_head* head = &std::get<1>(attr_rate_[attr_id]);
list_head* pos = nullptr;
list_head* next = nullptr;
int i = 0;
list_for_each_safe(pos, next, head) {
if (idx == -1 || idx == i) {
AttrRate* e = list_entry(pos,
AttrRate,
entry);
list_del_init(&e->entry);
delete e;
if (idx > -1) {
break;
}
}
++i;
}
RecalcAttrRate(attr_id);
}
}
}
void Ability::GMClearBaseAttr(int type)
{
for (auto& tuple : attr_abs_) {
std::get<0>(tuple) = 0.0f;
while (!list_empty(&std::get<1>(tuple))) {
AttrAbs* e = list_first_entry(&std::get<1>(tuple),
AttrAbs,
entry);
e->ptr->data = nullptr;
list_del_init(&e->entry);
delete e;
}
}
for (auto& tuple : attr_rate_) {
std::get<0>(tuple) = 0.0f;
while (!list_empty(&std::get<1>(tuple))) {
AttrRate* e = list_first_entry(&std::get<1>(tuple),
AttrRate,
entry);
e->ptr->data = nullptr;
list_del_init(&e->entry);
delete e;
}
}
}
void Ability::GMDelGrowAttr(int type, int attr_id, int idx)
{
if (IsValidHumanAttr(attr_id)) {
if (type == 1) {
list_head* head = &std::get<1>(attr_add_[attr_id]);
list_head* pos = nullptr;
list_head* next = nullptr;
int i = 0;
list_for_each_safe(pos, next, head) {
if (idx == -1 || idx == i) {
AttrAddition* e = list_entry(pos,
AttrAddition,
entry);
list_del_init(&e->entry);
delete e;
if (idx > -1) {
break;
}
}
++i;
}
RecalcAttrAddition(attr_id);
} else if (type == 2) {
list_head* head = &std::get<1>(attr_dec_[attr_id]);
list_head* pos = nullptr;
list_head* next = nullptr;
int i = 0;
list_for_each_safe(pos, next, head) {
if (idx == -1 || idx == i) {
AttrRuduce* e = list_entry(pos,
AttrRuduce,
entry);
list_del_init(&e->entry);
delete e;
if (idx > -1) {
break;
}
}
++i;
}
RecalcAttrRuduce(attr_id);
}
} else if (IsValidHumanVirtualAttr(attr_id)) {
if (type == 1) {
list_head* head = &std::get<1>(vattr_add_[attr_id - kHVAT_Begin]);
list_head* pos = nullptr;
list_head* next = nullptr;
int i = 0;
list_for_each_safe(pos, next, head) {
if (idx == -1 || idx == i) {
AttrAddition* e = list_entry(pos,
AttrAddition,
entry);
list_del_init(&e->entry);
delete e;
if (idx > -1) {
break;
}
}
++i;
}
RecalcAttrAddition(attr_id);
} else if (type == 2) {
list_head* head = &std::get<1>(vattr_dec_[attr_id - kHVAT_Begin]);
list_head* pos = nullptr;
list_head* next = nullptr;
int i = 0;
list_for_each_safe(pos, next, head) {
if (idx == -1 || idx == i) {
AttrRuduce* e = list_entry(pos,
AttrRuduce,
entry);
list_del_init(&e->entry);
delete e;
if (idx > -1) {
break;
}
}
++i;
}
RecalcAttrRuduce(attr_id);
}
}
}
void Ability::GMClearGrowAttr(int type)
{
for (auto& tuple : attr_add_) {
std::get<0>(tuple) = 0.0f;
while (!list_empty(&std::get<1>(tuple))) {
AttrAddition* e = list_first_entry(&std::get<1>(tuple),
AttrAddition,
entry);
e->ptr->data = nullptr;
list_del_init(&e->entry);
delete e;
}
}
for (auto& tuple : attr_dec_) {
std::get<0>(tuple) = 0.0f;
while (!list_empty(&std::get<1>(tuple))) {
AttrRuduce* e = list_first_entry(&std::get<1>(tuple),
AttrRuduce,
entry);
e->ptr->data = nullptr;
list_del_init(&e->entry);
delete e;
}
}
for (auto& tuple : vattr_add_) {
std::get<0>(tuple) = 0.0f;
while (!list_empty(&std::get<1>(tuple))) {
AttrAddition* e = list_first_entry(&std::get<1>(tuple),
AttrAddition,
entry);
e->ptr->data = nullptr;
list_del_init(&e->entry);
delete e;
}
}
for (auto& tuple : vattr_dec_) {
std::get<0>(tuple) = 0.0f;
while (!list_empty(&std::get<1>(tuple))) {
AttrRuduce* e = list_first_entry(&std::get<1>(tuple),
AttrRuduce,
entry);
e->ptr->data = nullptr;
list_del_init(&e->entry);
delete e;
}
}
}
std::vector<std::string> Ability::GMShowAttrs()
{
std::vector<std::string> strings;
{
std::vector<std::string> tmp_strings;
int attr_id = 0;
for (auto& tuple : attr_abs_) {
list_head* head = &std::get<1>(tuple);
list_head* pos = nullptr;
list_head* next = nullptr;
std::string data = a8::Format("attr_id:%d value:%f [", {attr_id, std::get<0>(tuple)});
int i = 0;
list_for_each_safe(pos, next, head) {
AttrAbs* e = list_entry(pos,
AttrAbs,
entry);
data += "" + a8::XValue(e->value).GetString() + ",";
++i;
}
if (i > 0) {
data += "]";
tmp_strings.push_back(data);
}
++attr_id;
}
strings.push_back("基础属性定值:");
if (tmp_strings.empty()) {
strings.push_back("");
} else {
for (auto& str : tmp_strings) {
strings.push_back(str);
}
}
}
{
std::vector<std::string> tmp_strings;
int attr_id = 0;
for (auto& tuple : attr_rate_) {
list_head* head = &std::get<1>(tuple);
list_head* pos = nullptr;
list_head* next = nullptr;
std::string data = a8::Format("attr_id:%d value:%f [", {attr_id, std::get<0>(tuple)});
int i = 0;
list_for_each_safe(pos, next, head) {
AttrRate* e = list_entry(pos,
AttrRate,
entry);
data += "" + a8::XValue(e->value).GetString() + ",";
++i;
}
if (i > 0) {
data += "]";
tmp_strings.push_back(data);
}
++attr_id;
}
strings.push_back("基础属性百分比:");
if (tmp_strings.empty()) {
strings.push_back("");
} else {
for (auto& str : tmp_strings) {
strings.push_back(str);
}
}
}
{
std::vector<std::string> tmp_strings;
int attr_id = 0;
for (auto& tuple : attr_add_) {
list_head* head = &std::get<1>(tuple);
list_head* pos = nullptr;
list_head* next = nullptr;
std::string data = a8::Format("attr_id:%d value:%f [", {attr_id, std::get<0>(tuple)});
int i = 0;
list_for_each_safe(pos, next, head) {
AttrAddition* e = list_entry(pos,
AttrAddition,
entry);
data += "" + a8::XValue(e->value).GetString() + ",";
++i;
}
if (i > 0) {
data += "]";
tmp_strings.push_back(data);
}
++attr_id;
}
strings.push_back("成长属性增:");
if (tmp_strings.empty()) {
strings.push_back("");
} else {
for (auto& str : tmp_strings) {
strings.push_back(str);
}
}
}
{
std::vector<std::string> tmp_strings;
int attr_id = 0;
for (auto& tuple : vattr_add_) {
list_head* head = &std::get<1>(tuple);
list_head* pos = nullptr;
list_head* next = nullptr;
std::string data = a8::Format("attr_id:%d value:%f [", {attr_id + kHVAT_Begin,
std::get<0>(tuple)});
int i = 0;
list_for_each_safe(pos, next, head) {
AttrAddition* e = list_entry(pos,
AttrAddition,
entry);
data += "" + a8::XValue(e->value).GetString() + ",";
++i;
}
if (i > 0) {
data += "]";
tmp_strings.push_back(data);
}
++attr_id;
}
strings.push_back("成长属性增(虚):");
if (tmp_strings.empty()) {
strings.push_back("");
} else {
for (auto& str : tmp_strings) {
strings.push_back(str);
}
}
}
{
std::vector<std::string> tmp_strings;
int attr_id = 0;
for (auto& tuple : attr_dec_) {
list_head* head = &std::get<1>(tuple);
list_head* pos = nullptr;
list_head* next = nullptr;
std::string data = a8::Format("attr_id:%d value:%f [", {attr_id, std::get<0>(tuple)});
int i = 0;
list_for_each_safe(pos, next, head) {
AttrRuduce* e = list_entry(pos,
AttrRuduce,
entry);
data += "" + a8::XValue(e->value).GetString() + ",";
++i;
}
if (i > 0) {
data += "]";
tmp_strings.push_back(data);
}
++attr_id;
}
strings.push_back("成长属性减:");
if (tmp_strings.empty()) {
strings.push_back("");
} else {
for (auto& str : tmp_strings) {
strings.push_back(str);
}
}
}
{
std::vector<std::string> tmp_strings;
int attr_id = 0;
for (auto& tuple : vattr_dec_) {
list_head* head = &std::get<1>(tuple);
list_head* pos = nullptr;
list_head* next = nullptr;
std::string data = a8::Format("减 attr_id:%d value:%f [", {attr_id + kHVAT_Begin,
std::get<0>(tuple)});
int i = 0;
list_for_each_safe(pos, next, head) {
AttrRuduce* e = list_entry(pos,
AttrRuduce,
entry);
data += "" + a8::XValue(e->value).GetString() + ",";
++i;
}
if (i > 0) {
data += "]";
tmp_strings.push_back(data);
}
++attr_id;
}
strings.push_back("成长属性减(虚):");
if (tmp_strings.empty()) {
strings.push_back("");
} else {
for (auto& str : tmp_strings) {
strings.push_back(str);
}
}
}
return strings;
}
void Ability::IncSwitch(int type)
{
if (type >= kSwitchTimeBegin && type < kSwitchTimeEnd) {
++switch_times_[type];
} else {
abort();
}
}
void Ability::DecSwitch(int type)
{
if (type >= kSwitchTimeBegin && type < kSwitchTimeEnd) {
--switch_times_[type];
} else {
abort();
}
}
int Ability::GetSwitchTimes(int type)
{
if (type >= kSwitchTimeBegin && type < kSwitchTimeEnd) {
return switch_times_[type];
} else {
abort();
}
return 0;
}
AttrDirectHandle Ability::AddAttrDirect(int attr_id, float value)
{
if (IsValidHumanAttr(attr_id)) {
auto p = new AttrDirect(attr_id, value);
list_add_tail(&p->entry, &std::get<1>(attr_direct_[attr_id]));
RecalcAttrDirect(attr_id);
return p->ptr;
}
return AttrDirectHandle();
}
void Ability::RemoveAttrDirect(AttrDirectHandle handle)
{
if (!handle.expired()) {
auto p = handle.lock();
list_del_init(&p->data->entry);
RecalcAttrDirect(p->data->attr_id);
delete p->data;
}
}
float Ability::GetAttrDirect(int attr_id)
{
if (IsValidHumanAttr(attr_id)) {
return std::get<0>(attr_direct_[attr_id]);
} else {
return 0.0f;
}
}
void Ability::RecalcAttrDirect(int attr_id)
{
list_head* head = &std::get<1>(attr_direct_[attr_id]);
list_head* pos = nullptr;
list_head* next = nullptr;
float new_val = 0.0f;
list_for_each_safe(pos, next, head) {
AttrDirect* e = list_entry(pos,
AttrDirect,
entry);
new_val = std::max(e->value, new_val);
}
std::get<0>(attr_direct_[attr_id]) = new_val;
}