diff --git a/server/gameserver/ability.cc b/server/gameserver/ability.cc index f5c923b5..d879ea00 100644 --- a/server/gameserver/ability.cc +++ b/server/gameserver/ability.cc @@ -97,6 +97,28 @@ struct AttrRuduce } }; +struct AttrDirectPtr +{ + struct AttrDirect* data; + AttrDirectPtr(AttrDirect* data) { this->data = data; }; +}; + +struct AttrDirect +{ + list_head entry; + int attr_id; + float value; + std::shared_ptr ptr; + + AttrDirect(int attr_id, float value) + { + this->attr_id = attr_id; + this->value = value; + INIT_LIST_HEAD(&entry); + ptr = std::make_shared(this); + } +}; + Ability::Ability(CreatureWeakPtr owner) { for (auto& tuple : attr_abs_) { @@ -123,11 +145,14 @@ Ability::Ability(CreatureWeakPtr owner) 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))) { @@ -196,6 +221,17 @@ void Ability::Clear() 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(); @@ -906,3 +942,48 @@ int Ability::GetSwitchTimes(int type) } 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; +} diff --git a/server/gameserver/ability.h b/server/gameserver/ability.h index 6b598899..fcaf21a0 100644 --- a/server/gameserver/ability.h +++ b/server/gameserver/ability.h @@ -2,11 +2,6 @@ #include "attrdefine.h" #include "weakptr.h" -typedef std::weak_ptr AttrAdditionHandle; -typedef std::weak_ptr AttrRuduceHandle; -typedef std::weak_ptr AttrAbsHandle; -typedef std::weak_ptr AttrRateHandle; - class Ability { public: @@ -34,6 +29,10 @@ class Ability float GetAttrAddition(int attr_id); float GetAttrRuduce(int attr_id); + AttrDirectHandle AddAttrDirect(int attr_id, float value); + void RemoveAttrDirect(AttrDirectHandle handle); + float GetAttrDirect(int attr_id); + void GMDelBaseAttr(int type, int attr_id, int idx); void GMClearBaseAttr(int type); void GMDelGrowAttr(int type, int attr_id, int idx); @@ -45,6 +44,7 @@ private: void RecalcAttrRate(int attr_id); void RecalcAttrAddition(int attr_id); void RecalcAttrRuduce(int attr_id); + void RecalcAttrDirect(int attr_id); private: CreatureWeakPtr owner_; std::array, kHAT_End> attr_abs_ = {}; @@ -53,6 +53,7 @@ private: std::array, kHAT_End> attr_dec_ = {}; std::array, kHVAT_End - kHVAT_Begin> vattr_add_ = {}; std::array, kHVAT_End - kHVAT_Begin> vattr_dec_ = {}; + std::array, kHAT_End> attr_direct_ = {}; std::array switch_times_ = {}; std::map immune_tags_; diff --git a/server/gameserver/airraid.cc b/server/gameserver/airraid.cc index 9c7e2ba3..bd24e7cd 100644 --- a/server/gameserver/airraid.cc +++ b/server/gameserver/airraid.cc @@ -84,8 +84,8 @@ bool AirRaid::GenAirRaidPos(const mt::AirRaid* raid_meta, glm::vec3& center) } } } - #ifdef DEBUG1 - if (humans.size() > 0) { + #ifdef DEBUG + if (humans.size() > 0 && room_->debug_params.find(121) != room_->debug_params.end()) { center = humans[0]->GetPos().ToGlmVec3(); } #endif diff --git a/server/gameserver/buff/bufffactory.cc b/server/gameserver/buff/bufffactory.cc index 8cd14638..9558fd59 100644 --- a/server/gameserver/buff/bufffactory.cc +++ b/server/gameserver/buff/bufffactory.cc @@ -43,6 +43,7 @@ #include "buff/modify_attr.h" #include "buff/modify_base_attr.h" #include "buff/modify_grow_attr.h" +#include "buff/direct_set_attr.h" #include "buff/vertigo.h" #include "buff/cond_add.h" #include "buff/distance_dmg_addition.h" @@ -56,6 +57,8 @@ std::shared_ptr BuffFactory::MakeBuff(const mt::Buff* buff_meta) return std::make_shared(); case kBET_ModifyGrowAttr: return std::make_shared(); + case kBET_DirectSetAttr: + return std::make_shared(); case kBET_SummonLoot: return std::make_shared(); case kBET_DistanceDmgAddition: diff --git a/server/gameserver/buff/callfunc.cc b/server/gameserver/buff/callfunc.cc index 2ef8c97b..1520c47d 100644 --- a/server/gameserver/buff/callfunc.cc +++ b/server/gameserver/buff/callfunc.cc @@ -152,6 +152,12 @@ void CallFuncBuff::Activate() DecSkillCd(); } break; + case BuffCallFunc_e::kRefreshHp: + { + owner->SetHP(owner->GetMaxHP()); + owner->room->frame_event.AddHpChg(owner->GetWeakPtrRef()); + } + break; default: { } diff --git a/server/gameserver/buff/callfunc.h b/server/gameserver/buff/callfunc.h index b28b7b49..c070c926 100644 --- a/server/gameserver/buff/callfunc.h +++ b/server/gameserver/buff/callfunc.h @@ -24,7 +24,8 @@ A8_DECLARE_CLASS_ENUM(BuffCallFunc_e, int, kSummonObstacleSepcPoint = 24, kSummonObstacleSpecDistance = 25, kClearSummonObstacle = 26, - kDecSkillCd = 27 + kDecSkillCd = 27, + kRefreshHp = 28 ); diff --git a/server/gameserver/buff/direct_set_attr.cc b/server/gameserver/buff/direct_set_attr.cc new file mode 100644 index 00000000..80075279 --- /dev/null +++ b/server/gameserver/buff/direct_set_attr.cc @@ -0,0 +1,26 @@ +#include "precompile.h" + +#include "buff/direct_set_attr.h" + +#include "creature.h" +#include "human.h" +#include "car.h" +#include "ability.h" + +#include "mt/Buff.h" + +void DirectSetAttrBuff::Activate() +{ + int attr_id = meta->_int_buff_param1; + float value = meta->GetBuffParam2(this); + if (IsValidHumanAttr(attr_id)) { + handle_ = owner->GetAbility()->AddAttrDirect(attr_id, value); + } +} + +void DirectSetAttrBuff::Deactivate() +{ + if (!handle_.expired()) { + owner->GetAbility()->RemoveAttrDirect(handle_); + } +} diff --git a/server/gameserver/buff/direct_set_attr.h b/server/gameserver/buff/direct_set_attr.h new file mode 100644 index 00000000..6cc514c8 --- /dev/null +++ b/server/gameserver/buff/direct_set_attr.h @@ -0,0 +1,14 @@ +#pragma once + +#include "buff.h" + +class DirectSetAttrBuff : public Buff +{ + public: + + virtual void Activate() override; + virtual void Deactivate() override; + + private: + AttrDirectHandle handle_; +}; diff --git a/server/gameserver/commands.cc b/server/gameserver/commands.cc index 5ca211e0..9ad0b813 100644 --- a/server/gameserver/commands.cc +++ b/server/gameserver/commands.cc @@ -7,6 +7,7 @@ #include "app.h" #include "ability.h" #include "movement.h" +#include "android.h" #include "cs_proto.pb.h" @@ -14,6 +15,7 @@ #include "mt/Text.h" #include "mt/Param.h" #include "mt/Buff.h" +#include "mt/Robot.h" void Player::_CMExecCommand(f8::MsgHdr& hdr, const cs::CMExecCommand& msg) { @@ -114,6 +116,26 @@ void Player::_CMExecCommand(f8::MsgHdr& hdr, const cs::CMExecCommand& msg) hum->GetMutablePos().FromGlmVec3(GetPos().ToGlmVec3()); room->grid_service->MoveCreature(hum); } + } else if (cmd == "randomobj" && cmds.size() >= 2) { + int weapon_id = a8::XValue(cmds[1]); + Human* target = nullptr; + room->TraverseHumanList + ( + [this, weapon_id, &target] (Human* hum) mutable + { + if (hum->IsAndroid() && !hum->dead && hum->team_id != team_id) { + if (hum->AsAndroid()->robot_meta->weapon_id() == weapon_id) { + target = hum; + return false; + } + } + return true; + }); + if (target) { + target->GetMovement()->ClearPath(); + target->GetMutablePos().FromGlmVec3(GetPos().ToGlmVec3()); + room->grid_service->MoveCreature(target); + } } else if (cmd == "getattr" && cmds.size() >= 2) { int attr_id = a8::XValue(cmds[1]); float abs_val = GetAbility()->GetAttrAbs(attr_id); @@ -133,6 +155,10 @@ void Player::_CMExecCommand(f8::MsgHdr& hdr, const cs::CMExecCommand& msg) #if DEBUG room->debug_params[119] = 1; #endif + } else if (cmd == "airraid") { + #if DEBUG + room->debug_params[121] = 1; + #endif } else if (cmd == "autodie") { #if DEBUG if (cmds.size() >= 2) { diff --git a/server/gameserver/constant_export.h b/server/gameserver/constant_export.h index a9f27dbf..464cc26d 100644 --- a/server/gameserver/constant_export.h +++ b/server/gameserver/constant_export.h @@ -52,7 +52,7 @@ A8_DECLARE_ENUM(BuffEffectType_e, kBET_DelayAddBuff = 18, //延迟加buff kBET_ModifyBaseAttr = 19, kBET_ModifyGrowAttr = 20, - kBET_UnUse21 = 21, + kBET_DirectSetAttr = 21, kBET_UnUse22 = 22, kBET_HunLuan = 23, //混乱,在烟雾弹中不自动瞄准 kBET_Fly = 24, //飞行中 diff --git a/server/gameserver/creature.cc b/server/gameserver/creature.cc index 8b7af869..cc3d756d 100644 --- a/server/gameserver/creature.cc +++ b/server/gameserver/creature.cc @@ -1808,12 +1808,7 @@ float Creature::GetHP() float Creature::GetMaxHP() { -#if 1 return ability.max_hp; -#else - return ability.max_hp * (1 + GetAbility()->GetAttrRate(kHAT_MaxHp)) + - GetAbility()->GetAttrAbs(kHAT_MaxHp); -#endif } float Creature::GetHPRate() diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 58c417d4..5e4a1398 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -1242,6 +1242,9 @@ void Human::DeadDrop() } } } + { + on_dead_remove_objects_.clear(); + } { if (GetInventory(IS_GEMSTONE) > 0 && gemstone > 0) { room->frame_event.AddPropChg @@ -1264,9 +1267,6 @@ void Human::DeadDrop() SyncVolume(IS_GEMSTONE); } } - { - on_dead_remove_objects_.clear(); - } MarkSyncActivePlayer(__FILE__, __LINE__, __func__); } diff --git a/server/gameserver/mtb/SkillNumber.h b/server/gameserver/mtb/SkillNumber.h index 146a9491..00eac47b 100644 --- a/server/gameserver/mtb/SkillNumber.h +++ b/server/gameserver/mtb/SkillNumber.h @@ -12,7 +12,7 @@ namespace mtb a8::reflect::Class* GetClass() const; int skill_id() const { return skill_id_; }; int skill_type() const { return skill_type_; }; - int number() const { return number_; }; + float number() const { return number_; }; float damage() const { return damage_; }; float damage_addition() const { return damage_addition_; }; float damage_change() const { return damage_change_; }; @@ -58,7 +58,7 @@ namespace mtb int skill_id_ = 0; int skill_type_ = 0; - int number_ = 0; + float number_ = 0.0f; float damage_ = 0.0f; float damage_addition_ = 0.0f; float damage_change_ = 0.0f; diff --git a/server/gameserver/mtb/mtb.all.cc b/server/gameserver/mtb/mtb.all.cc index 35625213..f680923e 100644 --- a/server/gameserver/mtb/mtb.all.cc +++ b/server/gameserver/mtb/mtb.all.cc @@ -407,7 +407,7 @@ namespace mtb meta_class = new a8::reflect::Class("SkillNumber", 21, 0); meta_class->SetSimpleField(0, "skill_id", a8::reflect::ET_INT32, my_offsetof2(SkillNumber, skill_id_)); meta_class->SetSimpleField(1, "skill_type", a8::reflect::ET_INT32, my_offsetof2(SkillNumber, skill_type_)); - meta_class->SetSimpleField(2, "number", a8::reflect::ET_INT32, my_offsetof2(SkillNumber, number_)); + meta_class->SetSimpleField(2, "number", a8::reflect::ET_FLOAT, my_offsetof2(SkillNumber, number_)); meta_class->SetSimpleField(3, "damage", a8::reflect::ET_FLOAT, my_offsetof2(SkillNumber, damage_)); meta_class->SetSimpleField(4, "damage_addition", a8::reflect::ET_FLOAT, my_offsetof2(SkillNumber, damage_addition_)); meta_class->SetSimpleField(5, "damage_change", a8::reflect::ET_FLOAT, my_offsetof2(SkillNumber, damage_change_)); diff --git a/server/gameserver/netdata.cc b/server/gameserver/netdata.cc index b1198b1a..e8c592be 100644 --- a/server/gameserver/netdata.cc +++ b/server/gameserver/netdata.cc @@ -746,18 +746,23 @@ float BattleDataContext::CalcDmg(Explosion* e) float BattleDataContext::GetTotalAtk(IBullet* bullet) { - float total_atk = (GetHeroTotalAtk() / 100) * GetWeaponAtk(bullet); - return total_atk; -} - -float BattleDataContext::GetHP() -{ - return hero_ability_->GetHP(); + float direct_atk = owner_.Get()->GetAbility()->GetAttrDirect(kHAT_Atk); + if (direct_atk > 0.001f) { + return direct_atk; + } else { + float total_atk = (GetHeroTotalAtk() / 100) * GetWeaponAtk(bullet); + return total_atk; + } } float BattleDataContext::GetMaxHP() { - return hero_ability_->GetHP(); + float hp = hero_ability_->GetHP(); + hp += owner_.Get()->GetAbility()->GetAttrAbs(kHAT_Hp); + hp *= 1.0f + owner_.Get()->GetAbility()->GetAttrRate(kHAT_Hp); + hp *= 1.0f + owner_.Get()->GetAbility()->GetAttrAddition(kHAT_Hp) - + owner_.Get()->GetAbility()->GetAttrRuduce(kHAT_Hp); + return hp; } float BattleDataContext::GetDef() diff --git a/server/gameserver/trigger.cc b/server/gameserver/trigger.cc index 742c23f3..6873ffde 100644 --- a/server/gameserver/trigger.cc +++ b/server/gameserver/trigger.cc @@ -228,7 +228,9 @@ void Trigger::HpChg() break; } #if 1 - TryAddBuffs(buff, buff->meta->_int_buff_param1, buff->meta->_buff_param4_int_list); + if (match) { + TryAddBuffs(buff, buff->meta->_int_buff_param1, buff->meta->_buff_param4_int_list); + } #else if (match) { TryAddBuffs(buff, buff->meta->_int_buff_param1, buff->meta->_buff_param4_int_list); diff --git a/server/gameserver/types.h b/server/gameserver/types.h index 2218bab0..a935d4f2 100644 --- a/server/gameserver/types.h +++ b/server/gameserver/types.h @@ -93,3 +93,9 @@ class IBullet virtual float GetHitRadius() = 0; virtual void ProcRequestBulletDmg(int shield_hit, int strength_wall_uniid, int target_uniid, const glm::vec3& pos) = 0; }; + +typedef std::weak_ptr AttrAdditionHandle; +typedef std::weak_ptr AttrRuduceHandle; +typedef std::weak_ptr AttrAbsHandle; +typedef std::weak_ptr AttrRateHandle; +typedef std::weak_ptr AttrDirectHandle; diff --git a/server/tools/protobuild/mt.proto b/server/tools/protobuild/mt.proto index 2017df52..b03d0984 100755 --- a/server/tools/protobuild/mt.proto +++ b/server/tools/protobuild/mt.proto @@ -322,7 +322,7 @@ message SkillNumber { required int32 skill_id = 1; optional int32 skill_type = 2; - optional int32 number = 3; + optional float number = 3; optional float damage = 4; optional float damage_addition = 5; optional float damage_change = 6;