aozhiwei 9cbec34fe7 1
2023-04-06 17:15:32 +08:00

171 lines
4.9 KiB
C++

#include "precompile.h"
#include "hero.h"
#include "room.h"
#include "human.h"
#include "incubator.h"
#include "roomobstacle.h"
#include "gridservice.h"
#include "glmhelper.h"
#include "stats.h"
#include "pvedata.h"
#include "mt/Param.h"
#include "mt/Hero.h"
#include "mt/PveGemini.h"
#include "mt/PveGeminiMode.h"
#include "mt/PveGeminiContent.h"
#include "mt/Text.h"
void PveData::AddDamageInfo(int sender_id, int receiver_id, float dmg)
{
auto itr = damage_hash_.find(receiver_id);
if (itr == damage_hash_.end()) {
damage_hash_[receiver_id] = std::map<int, float>();
}
itr = damage_hash_.find(receiver_id);
auto itr2 = itr->second.find(sender_id);
if (itr2 != itr->second.end()) {
itr2->second += dmg;
} else {
itr->second[sender_id] = dmg;
}
}
void PveData::OnBeKill(Hero* hero)
{
Room* room = hero->room;
auto itr = damage_hash_.find(hero->GetUniId());
if (itr != damage_hash_.end()) {
float total_dmg = 0;
for (auto& pair : itr->second) {
total_dmg += pair.second;
}
if (total_dmg > 0) {
float base_score = 0;
if (room->IsDestoryRoom()) {
base_score = std::get<0>(hero->meta->_pve_score);
} else {
base_score = std::get<1>(hero->meta->_pve_score);
}
for (auto& pair : itr->second) {
Human* hum = room->GetHumanByUniId(pair.first);
if (hum) {
int win_score = pair.second / total_dmg * base_score;
#ifdef DEBUG
a8::XPrintf("kill_score:%f \n", {win_score});
#endif
hum->WinPveScore(win_score);
}
}
}
room->NotifyUiUpdate();
}
if (hero->is_pve_boss) {
room->TraverseHumanList
(
[] (Human* hum) -> bool
{
if (!hum->dead) {
hum->stats->pve_kill_boss = true;
}
return true;
}
);
pve_kill_boss = true;
boss_state = 2;
#ifdef DEBUG
a8::XPrintf("onKill pve_boss\n", {});
#endif
}
#ifdef DEBUG
a8::XPrintf("PveData::OnBeKill wave:%d refreshed_mon:%d killed_num:%d\n",
{
GetWave(),
refreshed_mon,
killed_num
});
#endif
if (refreshed_mon > 0) {
if (killed_num >= refreshed_mon) {
if (GetWave() < room->pve_mode_meta->_round_score.size()) {
int win_score = room->pve_mode_meta->_round_score[GetWave()];
room->TraverseHumanList
(
[this, win_score] (Human* hum)
{
if (!hum->dead) {
#ifdef DEBUG
a8::XPrintf("round_score:%f \n", {win_score});
#endif
hum->WinPveScore(win_score);
}
return true;
});
}
if (room->IsDestoryRoom()) {
if (GetWave() + 1 < max_wave) {
if (GetWave() < room->pve_mode_meta->_next_door.size()) {
glm::vec3 point = room->pve_mode_meta->_next_door[room->pve_data.GetWave()];
FlyDoor(room, point, 50);
}
}
} else {
if (GetWave() + 1 < max_wave) {
room->GetIncubator()->NextWave();
}
}
}
}
}
void PveData::FlyDoor(Room* room, glm::vec3& point, int radius)
{
#ifdef DEBUG
a8::XPrintf("FlyDoor wave:%d refreshed_mon:%d killed_num:%d\n",
{
GetWave(),
refreshed_mon,
killed_num
});
#endif
room->xtimer.SetTimeoutEx
(
room->pve_mode_meta->wave_prepare_time() * SERVER_FRAME_RATE,
[room, point, radius]
(int event, const a8::Args* args)
{
if (a8::TIMER_EXEC_EVENT == event) {
room->TraverseHumanList
(
[room, &point, radius] (Human* hum)
{
glm::vec3 dir = GlmHelper::UP;
GlmHelper::RotateY(dir, a8::RandAngle());
glm::vec3 new_pos = point + dir * (float)a8::RandEx(1, radius);
hum->GetMutablePos().FromGlmVec3(new_pos);
//hum->TryAddBuff(hum, 1025);
room->grid_service->MoveCreature(hum);
return true;
});
}
},
&room->xtimer_attacher_);
room->GetIncubator()->NextWave();
}
int PveData::GetPassedWave()
{
if (boss_state == 2) {
return GetWave() + 1;
} else {
return GetWave();
}
}