848 lines
27 KiB
C++
848 lines
27 KiB
C++
#include "precompile.h"
|
|
|
|
#include <float.h>
|
|
|
|
#include <a8/mutable_xobject.h>
|
|
#include <a8/collision.h>
|
|
|
|
#include "human.h"
|
|
#include "cs_proto.pb.h"
|
|
#include "metamgr.h"
|
|
#include "room.h"
|
|
#include "collider.h"
|
|
#include "loot.h"
|
|
#include "app.h"
|
|
#include "roommgr.h"
|
|
#include "android.h"
|
|
#include "gamelog.h"
|
|
#include "typeconvert.h"
|
|
#include "player.h"
|
|
|
|
#include "framework/cpp/utils.h"
|
|
#include "framework/cpp/httpclientpool.h"
|
|
|
|
const int kReviveTimeAdd = 3;
|
|
|
|
Human::Human():Entity()
|
|
{
|
|
}
|
|
|
|
Human::~Human()
|
|
{
|
|
}
|
|
|
|
void Human::Initialize()
|
|
{
|
|
Entity::Initialize();
|
|
CreateSnake();
|
|
RecalcSelfCollider();
|
|
observers_.insert(this);
|
|
}
|
|
|
|
void Human::FillMFObjectPart(cs::MFObjectPart* part_data)
|
|
{
|
|
part_data->set_object_type(ET_Player);
|
|
cs::MFPlayerPart* p = part_data->mutable_union_obj_1();
|
|
p->set_obj_uniid(entity_uniid);
|
|
FillMFSnake(p->mutable_snake());
|
|
}
|
|
|
|
void Human::FillMFObjectFull(cs::MFObjectFull* full_data)
|
|
{
|
|
full_data->set_object_type(ET_Player);
|
|
cs::MFPlayerFull* p = full_data->mutable_union_obj_1();
|
|
p->set_obj_uniid(entity_uniid);
|
|
FillMFSnake(p->mutable_snake());
|
|
|
|
p->set_dead(dead);
|
|
p->set_disconnected(disconnected);
|
|
p->set_kill_count(stats.kills);
|
|
if (dead) {
|
|
p->set_killer_name(stats.killer_name);
|
|
p->set_killer_id(stats.killer_id);
|
|
if (real_dead){
|
|
p->set_can_revive(false);
|
|
} else {
|
|
p->set_can_revive(true);
|
|
int countdown = std::ceil(room->xtimer.GetRemainTime(revive_timer) / SERVER_FRAME_RATE);
|
|
countdown = std::max(0, countdown - kReviveTimeAdd);
|
|
p->set_revive_countdown(countdown);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Human::FillMFPlayerStats(cs::MFPlayerStats* stats_pb)
|
|
{
|
|
stats_pb->set_player_id(entity_uniid);
|
|
stats_pb->set_player_avatar_url(avatar_url);
|
|
|
|
if (!dead) {
|
|
stats_pb->set_time_alive(room->frame_no * 1000.0f / SERVER_FRAME_RATE);
|
|
} else {
|
|
stats_pb->set_time_alive(dead_frameno * 1000.0f / SERVER_FRAME_RATE);
|
|
}
|
|
stats_pb->set_kills(stats.kills);
|
|
stats_pb->set_damage_amount(stats.damage_amount_out);
|
|
stats_pb->set_heal_amount(stats.heal_amount);
|
|
|
|
stats_pb->set_history_time_alive(stats.history_time_alive);
|
|
stats_pb->set_history_kills(stats.history_kills);
|
|
stats_pb->set_history_damage_amount(stats.history_damage_amount);
|
|
stats_pb->set_history_heal_amount(stats.history_heal_amount);
|
|
|
|
stats_pb->set_gold(stats.gold);
|
|
stats_pb->set_score(stats.score);
|
|
stats_pb->set_pass_score(stats.pass_score);
|
|
stats_pb->set_rank_score(stats.rank_score);
|
|
stats_pb->set_has_pass(has_pass);
|
|
|
|
stats_pb->set_dead(dead);
|
|
stats_pb->set_killer_id(stats.killer_id);
|
|
stats_pb->set_killer_name(stats.killer_name);
|
|
{
|
|
Player* killer = room->GetPlayerByUniId(stats.killer_id);
|
|
if (killer) {
|
|
stats_pb->set_killer_avatar_url(killer->avatar_url);
|
|
stats_pb->set_killer_account_id(killer->account_id);
|
|
} else {
|
|
stats_pb->set_killer_avatar_url("");
|
|
stats_pb->set_killer_account_id("");
|
|
}
|
|
}
|
|
|
|
stats_pb->set_account_id(account_id);
|
|
|
|
for (auto& pair : stats.extra_drop) {
|
|
auto p = stats_pb->add_extra_drop();
|
|
p->set_key(pair.first);
|
|
p->set_value(pair.second);
|
|
}
|
|
}
|
|
|
|
void Human::GetAabbBox(AabbCollider& aabb_box)
|
|
{
|
|
abort();
|
|
#if 0
|
|
aabb_box.active = true;
|
|
aabb_box.owner = this;
|
|
aabb_box._min.x = -meta->p->radius();
|
|
aabb_box._min.y = -meta->p->radius();
|
|
aabb_box._max.x = meta->p->radius();
|
|
aabb_box._max.y = meta->p->radius();
|
|
#endif
|
|
}
|
|
|
|
void Human::FillMFTeamData(cs::MFTeamData* team_data)
|
|
{
|
|
#if 1
|
|
{
|
|
#else
|
|
if (room->gas_data.gas_mode == GasJump ||
|
|
room->frame_no - last_sync_teamdata_frameno_ > SERVER_FRAME_RATE * 2) {
|
|
#endif
|
|
last_sync_teamdata_frameno_ = room->frame_no;
|
|
team_data->set_player_id(entity_uniid);
|
|
team_data->set_name(name);
|
|
TypeConvert::ToPb(pos, team_data->mutable_pos());
|
|
team_data->set_disconnected(false);
|
|
team_data->set_dead(dead);
|
|
}
|
|
}
|
|
|
|
void Human::RecalcSelfCollider()
|
|
{
|
|
#if 0
|
|
if (!self_collider_) {
|
|
self_collider_ = new CircleCollider();
|
|
self_collider_->owner = this;
|
|
AddCollider(self_collider_);
|
|
}
|
|
self_collider_->pos = a8::Vec2();
|
|
self_collider_->rad = meta->p->radius();
|
|
#endif
|
|
}
|
|
|
|
void Human::SyncAroundPlayers(const char* file, int line, const char* func)
|
|
{
|
|
for (auto& cell : grid_list) {
|
|
for (Human* hum : cell->human_list) {
|
|
hum->AddToNewObjects(this);
|
|
assert(hum->part_objects.find(this) != hum->part_objects.end());
|
|
if (hum->part_objects.find(this) == hum->part_objects.end()) {
|
|
if (a8::XGetTickCount() - room->last_debugout_tick > 1000 * 10) {
|
|
room->last_debugout_tick = a8::XGetTickCount();
|
|
a8::UdpLog::Instance()->Warning("SyncAroundPlayers error file:%s line:%d func:%s",
|
|
{
|
|
file,
|
|
line,
|
|
func
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Human::FillSMGameOver(cs::SMGameOver& msg)
|
|
{
|
|
if (stats.rank <= 0) {
|
|
std::vector<Human*> human_list;
|
|
room->TouchHumanList(a8::XParams(),
|
|
[&human_list] (Human* hum, a8::XParams& param) -> bool
|
|
{
|
|
if (hum->leave_frameno_ == 0 ||
|
|
hum->leave_frameno_ > hum->room->battle_start_frameno_) {
|
|
human_list.push_back(hum);
|
|
}
|
|
return true;
|
|
});
|
|
std::sort(human_list.begin(), human_list.end(),
|
|
[] (Human* a, Human* b )
|
|
{
|
|
if (a->dead_frameno == b->dead_frameno) {
|
|
return a->entity_uniid < b->entity_uniid;
|
|
} else {
|
|
return a->dead_frameno == 0 ||
|
|
(b->dead_frameno != 0 && a->dead_frameno > b->dead_frameno);
|
|
}
|
|
});
|
|
int rank = human_list.size();
|
|
for (size_t i = 0; i < human_list.size(); ++i) {
|
|
if (human_list[i] == this) {
|
|
rank = i + 1;
|
|
break;
|
|
}
|
|
}
|
|
if (room->GetAliveTeamNum() == 1) {
|
|
std::set<Human*>* alive_team = room->GetAliveTeam();
|
|
if (alive_team == team_members) {
|
|
rank = 1;
|
|
}
|
|
}
|
|
stats.rank = rank;
|
|
}
|
|
|
|
msg.set_team_id(team_id);
|
|
msg.set_team_rank(stats.rank);
|
|
msg.set_team_allcnt(1);
|
|
msg.set_game_over(room->game_over);
|
|
msg.set_victory(!dead);
|
|
msg.set_room_uuid(a8::XValue(room->room_uuid));
|
|
|
|
cs::MFPlayerStats* p = msg.add_player_stats();
|
|
FillMFPlayerStats(p);
|
|
}
|
|
|
|
void Human::BeKill(int killer_id, const std::string& killer_name)
|
|
{
|
|
}
|
|
|
|
void Human::AddToNewObjects(Entity* entity)
|
|
{
|
|
new_objects.insert(entity);
|
|
}
|
|
|
|
void Human::AddToPartObjects(Entity* entity)
|
|
{
|
|
part_objects.insert(entity);
|
|
}
|
|
|
|
void Human::RemovePartObjects(Entity* entity)
|
|
{
|
|
part_objects.erase(entity);
|
|
}
|
|
|
|
void Human::RemoveObjects(Entity* entity)
|
|
{
|
|
del_objects.insert(entity->entity_uniid);
|
|
}
|
|
|
|
void Human::AddOutObjects(Entity* entity)
|
|
{
|
|
out_objects.insert(entity->entity_uniid);
|
|
}
|
|
|
|
void Human::RemoveOutObjects(Entity* entity)
|
|
{
|
|
out_objects.erase(entity->entity_uniid);
|
|
}
|
|
|
|
bool Human::HasLiveTeammate()
|
|
{
|
|
if (team_members) {
|
|
for (auto& hum : *team_members) {
|
|
if (hum != this && !hum->dead) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void Human::RefreshView()
|
|
{
|
|
for (auto& cell : grid_list) {
|
|
for (Human* hum : cell->human_list) {
|
|
hum->AddToNewObjects(this);
|
|
hum->AddToPartObjects(this);
|
|
AddToNewObjects(hum);
|
|
AddToPartObjects(hum);
|
|
}
|
|
for (Entity* entity : cell->entity_list) {
|
|
switch (entity->entity_type) {
|
|
case ET_Loot:
|
|
{
|
|
AddToNewObjects(entity);
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Human::OnGridListChange(std::set<GridCell*>& old_grid_list,
|
|
std::set<GridCell*>& inc_grid_list,
|
|
std::set<GridCell*>& dec_grid_list
|
|
)
|
|
{
|
|
for (GridCell* cell : inc_grid_list) {
|
|
for (Human* hum : cell->human_list) {
|
|
if (!room->grid_service.HumanInGridList(hum, old_grid_list)) {
|
|
hum->AddToNewObjects(this);
|
|
hum->AddToPartObjects(this);
|
|
hum->RemoveOutObjects(this);
|
|
AddToNewObjects(hum);
|
|
AddToPartObjects(hum);
|
|
RemoveOutObjects(hum);
|
|
}
|
|
}
|
|
for (Entity* entity : cell->entity_list) {
|
|
if (!room->grid_service.EntityInGridList(entity, old_grid_list)) {
|
|
switch (entity->entity_type) {
|
|
case ET_Loot:
|
|
{
|
|
AddToNewObjects(entity);
|
|
RemoveOutObjects(entity);
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for (GridCell* cell : dec_grid_list) {
|
|
for (Human* hum : cell->human_list) {
|
|
if (!room->grid_service.HumanInGridList(hum, grid_list)) {
|
|
AddOutObjects(hum);
|
|
hum->AddOutObjects(this);
|
|
}
|
|
}
|
|
for (Entity* entity : cell->entity_list) {
|
|
if (!room->grid_service.EntityInGridList(entity, grid_list)) {
|
|
switch (entity->entity_type) {
|
|
case ET_Loot:
|
|
{
|
|
AddOutObjects(entity);
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Human::FillMFActivePlayerData(cs::MFActivePlayerData* player_data)
|
|
{
|
|
}
|
|
|
|
void Human::FillMFGasData(cs::MFGasData* gas_data)
|
|
{
|
|
gas_data->set_mode(room->gas_data.gas_mode);
|
|
if (room->gas_data.gas_mode == GasInactive) {
|
|
long long duration = MetaMgr::Instance()->gas_inactive_time * SERVER_FRAME_RATE -
|
|
(room->frame_no - room->gas_data.gas_start_frameno);
|
|
gas_data->set_duration(std::max(duration * 50, (long long)1000) / 1000);
|
|
}
|
|
}
|
|
|
|
bool Human::CanSee(const Human* hum) const
|
|
{
|
|
return room->grid_service.InView(grid_id, hum->grid_id);
|
|
}
|
|
|
|
void Human::RecalcAttr()
|
|
{
|
|
}
|
|
|
|
void Human::RecalcBuff()
|
|
{
|
|
buff = HumanAbility();
|
|
}
|
|
|
|
void Human::AddObserver(Human* observer)
|
|
{
|
|
observers_.insert(observer);
|
|
}
|
|
|
|
void Human::RemoveObserver(Human* observer)
|
|
{
|
|
observers_.erase(observer);
|
|
}
|
|
|
|
void Human::SendUpdateMsg()
|
|
{
|
|
if (!follow_target_) {
|
|
cs::MFActivePlayerData* active_player_data_pb = nullptr;
|
|
if (send_msg_times == 0 || need_sync_active_player) {
|
|
active_player_data_pb = new cs::MFActivePlayerData();
|
|
FillMFActivePlayerData(active_player_data_pb);
|
|
need_sync_active_player = false;
|
|
}
|
|
|
|
cs::SMUpdate* msg = room->frame_maker.MakeUpdateMsg(this);
|
|
if (send_msg_times == 0 || last_sync_gas_frameno < room->gas_data.gas_start_frameno) {
|
|
last_sync_gas_frameno = room->gas_data.gas_start_frameno;
|
|
}
|
|
bool refreshed_view = false;
|
|
std::set<Entity*> view_objects;
|
|
for (Human* observer : observers_) {
|
|
msg->clear_team_data();
|
|
if (observer->team_members) {
|
|
for (auto& itr : *observer->team_members) {
|
|
if (itr != observer) {
|
|
itr->FillMFTeamData(msg->add_team_data());
|
|
}
|
|
}
|
|
}
|
|
if (observer != this && !observer->follow_synced_active_player) {
|
|
msg->set_active_player_id(entity_uniid);
|
|
FillMFActivePlayerData(msg->mutable_active_player_data());
|
|
if (!refreshed_view) {
|
|
for (auto& cell : grid_list) {
|
|
for (Human* hum : cell->human_list) {
|
|
view_objects.insert(hum);
|
|
}
|
|
for (Entity* entity : cell->entity_list) {
|
|
switch (entity->entity_type) {
|
|
case ET_Loot:
|
|
{
|
|
view_objects.insert(entity);
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
for (Entity* entity : view_objects) {
|
|
if (new_objects.find(entity) == new_objects.end()) {
|
|
entity->FillMFObjectFull(msg->add_full_objects());
|
|
}
|
|
}
|
|
refreshed_view = true;
|
|
}
|
|
observer->follow_synced_active_player = true;
|
|
} else {
|
|
if (active_player_data_pb) {
|
|
msg->set_active_player_id(entity_uniid);
|
|
*msg->mutable_active_player_data() = *active_player_data_pb;
|
|
} else {
|
|
msg->clear_active_player_id();
|
|
msg->clear_active_player_data();
|
|
}
|
|
}
|
|
observer->SendNotifyMsg(*msg);
|
|
}
|
|
delete msg;
|
|
|
|
if (active_player_data_pb) {
|
|
delete active_player_data_pb;
|
|
}
|
|
++send_msg_times;
|
|
}
|
|
ClearFrameData();
|
|
}
|
|
|
|
void Human::SendGameOver()
|
|
{
|
|
if (entity_subtype == EST_Player) {
|
|
//!!!必须要在SendNotifyMsg之前注意哦
|
|
if (!sent_battlereport_) {
|
|
SendBattleReport();
|
|
sent_battlereport_ = true;
|
|
GameLog::Instance()->GameEnd((Player*)this);
|
|
}
|
|
{
|
|
cs::SMGameOver msg;
|
|
FillSMGameOver(msg);
|
|
SendNotifyMsg(msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Human::FollowTarget(Human* target)
|
|
{
|
|
if (target == this) {
|
|
return;
|
|
}
|
|
if (follow_target_) {
|
|
follow_target_->RemoveObserver(this);
|
|
}
|
|
target->AddObserver(this);
|
|
follow_target_ = target;
|
|
follow_synced_active_player = false;
|
|
}
|
|
|
|
void Human::SendDebugMsg(const std::string& debug_msg)
|
|
{
|
|
cs::SMDebugMsg notify_msg;
|
|
notify_msg.set_debug_msg(debug_msg);
|
|
SendNotifyMsg(notify_msg);
|
|
}
|
|
|
|
void Human::SendRollMsg(const std::string& roll_msg)
|
|
{
|
|
room->xtimer.AddDeadLineTimerAndAttach(
|
|
0,
|
|
a8::XParams()
|
|
.SetSender(this)
|
|
.SetParam1(roll_msg),
|
|
[] (const a8::XParams& param)
|
|
{
|
|
Human* target = (Human*)param.sender.GetUserData();
|
|
std::string roll_msg = param.param1;
|
|
target->room->TouchHumanList(a8::XParams(),
|
|
[target, roll_msg] (Human* hum, a8::XParams& param) -> bool
|
|
{
|
|
if (target != hum) {
|
|
cs::SMRollMsg msg;
|
|
msg.set_msg(roll_msg);
|
|
hum->SendNotifyMsg(msg);
|
|
}
|
|
return true;
|
|
});
|
|
},
|
|
&xtimer_attacher.timer_list_
|
|
);
|
|
}
|
|
|
|
void Human::SendUIUpdate()
|
|
{
|
|
cs::SMUiUpdate notifymsg;
|
|
notifymsg.set_alive_count(room->AliveCount());
|
|
notifymsg.set_kill_count(stats.kills);
|
|
room->FillSMUiUpdate(notifymsg);
|
|
SendNotifyMsg(notifymsg);
|
|
}
|
|
|
|
void Human::SendWxVoip()
|
|
{
|
|
cs::SMWxVoip notifymsg;
|
|
if (!team_uuid.empty()) {
|
|
notifymsg.set_group_id(a8::XValue(room->room_uuid).GetString() + "_" + a8::XValue(team_id).GetString());
|
|
}
|
|
SendNotifyMsg(notifymsg);
|
|
}
|
|
|
|
void Human::_UpdateMove(int speed)
|
|
{
|
|
a8::Vec2 pre_node_pos = head_->pos;
|
|
SnakeBodyNode* pre_node = head_;
|
|
float node_dist = 2 * head_->radius * (1 - meta->p->body_interval());
|
|
{
|
|
a8::Vec2 old_pos = head_->pos;
|
|
head_->pos = head_->pos + move_dir * head_->speed;
|
|
}
|
|
{
|
|
for (auto& node : body_list) {
|
|
a8::Vec2 new_pos = (pre_node_pos + node->pos) / 2;
|
|
a8::Vec2 dist_vec = pre_node->pos - new_pos;
|
|
float move_dist = dist_vec.Norm() - node_dist;
|
|
|
|
pre_node_pos = node->pos;
|
|
if (std::abs(move_dist) > 0.00001f) {
|
|
a8::Vec2 dist_dir= dist_vec;
|
|
dist_dir.Normalize();
|
|
node->pos = new_pos + dist_dir * (move_dist / dist_vec.Norm());
|
|
} else {
|
|
node->pos = new_pos;
|
|
}
|
|
|
|
pre_node = node;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Human::ClearFrameData()
|
|
{
|
|
if (!new_objects.empty()) {
|
|
new_objects.clear();
|
|
}
|
|
if (!del_objects.empty()) {
|
|
for (auto& itr : del_objects) {
|
|
Entity* entity = room->GetEntityByUniId(itr);
|
|
if (entity) {
|
|
RemovePartObjects(entity);
|
|
}
|
|
}
|
|
del_objects.clear();
|
|
}
|
|
if (!out_objects.empty()) {
|
|
for (auto& itr : out_objects) {
|
|
Entity* entity = room->GetEntityByUniId(itr);
|
|
if (entity) {
|
|
RemovePartObjects(entity);
|
|
}
|
|
}
|
|
out_objects.clear();
|
|
}
|
|
if (!emotes_.empty()) {
|
|
emotes_.clear();
|
|
}
|
|
}
|
|
|
|
void Human::GenBattleReportData(a8::MutableXObject* params)
|
|
{
|
|
int rank = 0;
|
|
{
|
|
std::vector<Human*> human_list;
|
|
room->TouchHumanList(a8::XParams(),
|
|
[&human_list] (Human* hum, a8::XParams& param) -> bool
|
|
{
|
|
human_list.push_back(hum);
|
|
return true;
|
|
});
|
|
std::sort(human_list.begin(), human_list.end(),
|
|
[] (Human* a, Human* b )
|
|
{
|
|
if (a->dead_frameno == b->dead_frameno) {
|
|
return a->entity_uniid < b->entity_uniid;
|
|
} else {
|
|
return a->dead_frameno == 0 ||
|
|
(b->dead_frameno != 0 && a->dead_frameno > b->dead_frameno);
|
|
}
|
|
});
|
|
rank = human_list.size();
|
|
for (size_t i = 0; i < human_list.size(); ++i) {
|
|
if (human_list[i] == this) {
|
|
rank = i + 1;
|
|
break;
|
|
}
|
|
}
|
|
if (room->GetAliveTeamNum() == 1) {
|
|
std::set<Human*>* alive_team = room->GetAliveTeam();
|
|
if (alive_team == team_members) {
|
|
rank = 1;
|
|
}
|
|
}
|
|
}
|
|
stats.rank = rank;
|
|
params->SetVal("account_id", account_id);
|
|
params->SetVal("map_id", room->map_meta->p->map_id());
|
|
params->SetVal("map_name", room->map_meta->p->map_name());
|
|
params->SetVal("map_tpl_name", room->map_tpl_name);
|
|
params->SetVal("game_time", time(nullptr));
|
|
params->SetVal("hurt", stats.damage_amount_in);
|
|
params->SetVal("rank", rank);
|
|
params->SetVal("kills", stats.kills);
|
|
params->SetVal("harm", stats.damage_amount_out);
|
|
params->SetVal("add_HP", stats.heal_amount);
|
|
if (!dead) {
|
|
params->SetVal("alive_time", room->frame_no * 1000.0f / SERVER_FRAME_RATE);
|
|
} else {
|
|
params->SetVal("alive_time", dead_frameno * 1000.0f / SERVER_FRAME_RATE);
|
|
}
|
|
params->SetVal("team_status", team_members && team_members->size() > 1 ? 1 : 0);
|
|
params->SetVal("room_uuid", room->room_uuid);
|
|
|
|
int snipe_kill = 0;
|
|
int rifle_kill = 0;
|
|
int pistol_kill = 0;
|
|
int submachine_kill = 0;
|
|
params->SetVal("snipe_kill", snipe_kill);
|
|
params->SetVal("rifle_kill", rifle_kill);
|
|
params->SetVal("pistol_kill", pistol_kill);
|
|
params->SetVal("submachine_kill", submachine_kill);
|
|
|
|
params->SetVal("rescue_member", stats.rescue_member);
|
|
{
|
|
float rank_param = MetaMgr::Instance()->GetRankRewardParam(rank);
|
|
float kill_param = MetaMgr::Instance()->GetKillRewardParam(stats.kills);
|
|
int coin_num = (rank_param * MetaMgr::Instance()->rank_param) +
|
|
(kill_param * MetaMgr::Instance()->kill_param);
|
|
stats.gold = coin_num;
|
|
params->SetVal("coin_num", coin_num);
|
|
}
|
|
{
|
|
stats.pass_score = MetaMgr::Instance()->GetKillPointParam1(stats.kills);
|
|
stats.pass_score += MetaMgr::Instance()->GetRankPointParam1(rank);
|
|
stats.rank_score = MetaMgr::Instance()->GetKillPointParam2(stats.kills);
|
|
stats.rank_score += MetaMgr::Instance()->GetRankPointParam2(rank);
|
|
}
|
|
params->SetVal("score", 0);
|
|
params->SetVal("pass_score", has_pass ? stats.pass_score * 2 : stats.pass_score);
|
|
params->SetVal("rank_score", stats.rank_score);
|
|
}
|
|
|
|
void Human::SendBattleReport()
|
|
{
|
|
a8::MutableXObject* params = a8::MutableXObject::NewObject();
|
|
GenBattleReportData(params);
|
|
auto on_ok = [] (a8::XParams& param, a8::XObject& data)
|
|
{
|
|
};
|
|
auto on_error = [] (a8::XParams& param, const std::string& response)
|
|
{
|
|
a8::UdpLog::Instance()->Error("battleReport http error params: %s response: %s",
|
|
{
|
|
param.param2,
|
|
response
|
|
});
|
|
};
|
|
std::string url;
|
|
if (!f8::IsOnlineEnv()) {
|
|
if (App::Instance()->HasFlag(3)) {
|
|
url = "http://192.168.100.41/webapp/index.php?c=Role&a=battleReport";
|
|
} else {
|
|
url = "https://game2009api-test.kingsome.cn/webapp/index.php?c=Role&a=battleReport";
|
|
}
|
|
} else {
|
|
#if 1
|
|
url = "http://game2009api.kingsome.cn/webapp/index.php?c=Role&a=battleReport";
|
|
#else
|
|
url = "https://game2009api.kingsome.cn/webapp/index.php?c=Role&a=battleReport";
|
|
#endif
|
|
}
|
|
std::string data;
|
|
params->ToUrlEncodeStr(data);
|
|
f8::HttpClientPool::Instance()->HttpGet(
|
|
a8::XParams()
|
|
.SetSender(room->room_uuid)
|
|
.SetParam1(entity_uniid)
|
|
.SetParam2(data),
|
|
on_ok,
|
|
on_error,
|
|
url.c_str(),
|
|
*params,
|
|
MAX_SYS_HTTP_NUM + (entity_uniid % MAX_USER_HTTP_NUM)
|
|
);
|
|
delete params;
|
|
}
|
|
|
|
void Human::OnDie()
|
|
{
|
|
room->OnHumanDie(this);
|
|
SyncAroundPlayers(__FILE__, __LINE__, __func__);
|
|
{
|
|
std::set<Human*> over_humans;
|
|
if (!leave_) {
|
|
if (team_members) {
|
|
for (auto& member : *team_members) {
|
|
if (member->real_dead) {
|
|
over_humans.insert(member);
|
|
}
|
|
}
|
|
} else {
|
|
over_humans.insert(this);
|
|
}
|
|
}
|
|
if (room->GetAliveTeamNum() == 1) {
|
|
std::set<Human*>* alive_team = room->GetAliveTeam();
|
|
if (alive_team) {
|
|
for (Human* member : *alive_team) {
|
|
over_humans.insert(member);
|
|
}
|
|
}
|
|
}
|
|
for (Human* hum : over_humans) {
|
|
hum->SendGameOver();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Human::Revive()
|
|
{
|
|
auto callback =
|
|
[] (const a8::XParams& param)
|
|
{
|
|
Human* hum = (Human*)param.sender.GetUserData();
|
|
hum->dead = true;
|
|
hum->real_dead = true;
|
|
hum->OnDie();
|
|
};
|
|
int wait_revive_time = MetaMgr::Instance()->GetSysParamAsInt("revive_time", 25 + kReviveTimeAdd);
|
|
revive_timer = room->xtimer.AddDeadLineTimerAndAttach(SERVER_FRAME_RATE * wait_revive_time,
|
|
a8::XParams()
|
|
.SetSender(this),
|
|
callback,
|
|
&xtimer_attacher.timer_list_,
|
|
[] (const a8::XParams& param)
|
|
{
|
|
Human* hum = (Human*)param.sender.GetUserData();
|
|
hum->revive_timer = nullptr;
|
|
});
|
|
SyncAroundPlayers(__FILE__, __LINE__, __func__);
|
|
}
|
|
|
|
void Human::CreateSnake()
|
|
{
|
|
a8::Vec2 init_pos;
|
|
room->GenSnakeBornPos(init_pos);
|
|
|
|
head_ = new SnakeBodyNode();
|
|
head_->node_id = ++curr_node_id_;
|
|
head_->speed = meta->p->speed_normal();
|
|
head_->radius = meta->p->init_radius();
|
|
head_->pos = init_pos;
|
|
//head_->dir = meta->p->init_radius();
|
|
|
|
a8::Vec2 node_pos = init_pos;
|
|
SnakeBodyNode* pre_node = head_;
|
|
for (int i = 0; i < meta->p->init_body_size(); ++i) {
|
|
node_pos.y -= (1 - meta->p->body_interval()) * meta->p->init_radius();
|
|
SnakeBodyNode* node = new SnakeBodyNode();
|
|
node->node_id = ++curr_node_id_;
|
|
node->pre_node = pre_node;
|
|
node->speed = meta->p->speed_normal();
|
|
node->radius = meta->p->init_radius();
|
|
node->pos = node_pos;
|
|
body_list.push_back(node);
|
|
|
|
pre_node = node;
|
|
}
|
|
tail_ = pre_node;
|
|
|
|
}
|
|
|
|
void Human::FillMFSnake(cs::MFSnake* snake_pb)
|
|
{
|
|
{
|
|
cs::MFSnakeHead* head_pb = snake_pb->mutable_snake_head();
|
|
TypeConvert::ToPb(head_->pos, head_pb->mutable_pos());
|
|
TypeConvert::ToPb(head_->dir, head_pb->mutable_dir());
|
|
head_pb->set_radius(head_->radius);
|
|
head_pb->set_speed(head_->speed);
|
|
}
|
|
{
|
|
for (auto& body : body_list) {
|
|
TypeConvert::ToPb(
|
|
body->pos,
|
|
snake_pb->add_snake_body()->mutable_pos()
|
|
);
|
|
}
|
|
}
|
|
}
|