130 lines
3.8 KiB
C++
130 lines
3.8 KiB
C++
#include "precompile.h"
|
|
#include "hero.h"
|
|
#include "room.h"
|
|
#include "human.h"
|
|
#include "metadata.h"
|
|
#include "incubator.h"
|
|
#include "roomobstacle.h"
|
|
#include "gridservice.h"
|
|
|
|
#include "pvedata.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;
|
|
hum->WinPveScore(win_score);
|
|
}
|
|
}
|
|
}
|
|
room->NotifyUiUpdate();
|
|
}
|
|
|
|
|
|
if (hero->is_pve_boss) {
|
|
room->TraverseHumanList
|
|
(
|
|
a8::XParams(),
|
|
[] (Human* hum, a8::XParams& param) -> bool
|
|
{
|
|
hum->stats.pve_kill_boss = true;
|
|
return true;
|
|
}
|
|
);
|
|
pve_kill_boss = true;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
a8::XPrintf("PveData::OnBeKill wave:%d refreshed_mon:%d killed_num:%d\n",
|
|
{
|
|
wave,
|
|
refreshed_mon,
|
|
killed_num
|
|
});
|
|
#endif
|
|
|
|
if (refreshed_mon > 0) {
|
|
if (killed_num >= refreshed_mon) {
|
|
if (wave < room->pve_mode_meta->round_score.size()) {
|
|
int win_score = room->pve_mode_meta->round_score[wave];
|
|
room->TraverseHumanList
|
|
(
|
|
a8::XParams(),
|
|
[this, win_score] (Human* hum, a8::XParams& param)
|
|
{
|
|
hum->WinPveScore(win_score);
|
|
return true;
|
|
});
|
|
}
|
|
if (room->IsDestoryRoom()) {
|
|
if (wave < room->pve_mode_meta->next_door.size()) {
|
|
a8::Vec2 point = room->pve_mode_meta->next_door[room->pve_data.wave];
|
|
#if 0
|
|
room->CreateObstacle(PVE_DOOR_THING_ID, point.x, point.y);
|
|
#endif
|
|
FlyDoor(room, point, 50);
|
|
}
|
|
} else {
|
|
room->GetIncubator()->NextWave();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void PveData::FlyDoor(Room* room, a8::Vec2& point, int radius)
|
|
{
|
|
#ifdef DEBUG
|
|
a8::XPrintf("FlyDoor wave:%d refreshed_mon:%d killed_num:%d\n",
|
|
{
|
|
wave,
|
|
refreshed_mon,
|
|
killed_num
|
|
});
|
|
#endif
|
|
room->TraverseHumanList
|
|
(
|
|
a8::XParams(),
|
|
[this, room, &point, radius] (Human* hum, a8::XParams& param)
|
|
{
|
|
a8::Vec2 dir = a8::Vec2::UP;
|
|
dir.Rotate(a8::RandAngle());
|
|
a8::Vec2 new_pos = point + dir * a8::RandEx(1, radius);
|
|
hum->SetPos(new_pos);
|
|
//hum->TryAddBuff(hum, 1025);
|
|
room->grid_service->MoveCreature(hum);
|
|
return true;
|
|
});
|
|
room->GetIncubator()->NextWave();
|
|
}
|