2021-03-05 15:48:18 +08:00

161 lines
4.3 KiB
C++

#include "precompile.h"
#include "car.h"
#include "human.h"
#include "room.h"
#include "metamgr.h"
#include "loot.h"
#include "perfmonitor.h"
#include "typeconvert.h"
Car::Car():MoveableEntity()
{
++PerfMonitor::Instance()->entity_num[ET_Car];
}
Car::~Car()
{
--PerfMonitor::Instance()->entity_num[ET_Car];
}
void Car::Initialize()
{
MoveableEntity::Initialize();
}
void Car::FillMFObjectPart(Room* room, Human* hum, cs::MFObjectPart* part_data)
{
part_data->set_object_type(ET_Car);
cs::MFCarPart* p = part_data->mutable_union_obj_11();
p->set_obj_uniid(GetEntityUniId());
TypeConvert::ToPb(GetPos(), p->mutable_pos());
TypeConvert::ToPb(move_dir, p->mutable_dir());
}
void Car::FillMFObjectFull(Room* room, Human* hum, cs::MFObjectFull* full_data)
{
full_data->set_object_type(ET_Car);
cs::MFCarFull* p = full_data->mutable_union_obj_11();
p->set_obj_uniid(GetEntityUniId());
TypeConvert::ToPb(GetPos(), p->mutable_pos());
TypeConvert::ToPb(move_dir, p->mutable_dir());
p->set_car_id(meta->i->id());
p->set_driver(driver_ ? driver_->GetEntityUniId() : 0);
for (auto hum : passengers_) {
auto less_data = p->add_passengers();
hum->FillMFObjectLess(room, hum, less_data);
}
}
void Car::GetDown(Human* passenger)
{
if (later_removed_) {
return;
}
if (passengers_.find(passenger) == passengers_.end()) {
return;
}
if (driver_ == passenger) {
driver_ = nullptr;
}
if (meta->i->buffid()) {
passenger->RemoveBuffById(meta->i->buffid());
passenger->RecalcSelfCollider();
}
passengers_.erase(passenger);
if (passengers_.empty()) {
int loot_uniid = room->CreateLoot(meta->i->id(), GetPos(), 1, 1);
Entity* loot_entity = room->GetEntityByUniId(loot_uniid);
if (loot_entity && loot_entity->IsEntityType(ET_Loot)) {
((Loot*)loot_entity)->bullet_num = 0;
((Loot*)loot_entity)->param1 = 0;
((Loot*)loot_entity)->param2 = 0;
room->UpdateCarObject(car_uniid,
loot_entity->GetEntityUniId(),
loot_entity->GetPos());
}
room->TakeOffCarObject(loot_uniid, GetPos());
room->RemoveObjectLater(this);
later_removed_ = true;
}
passenger->SetCar(nullptr);
passenger->SetSeat(0);
passenger->car_weapon = Weapon();
passenger->CancelAction();
passenger->RemoveBuffByEffectId(kBET_Driver);
passenger->RemoveBuffByEffectId(kBET_Passenger);
room->frame_event.AddCarChg(passenger);
SyncAroundPlayers(__FILE__, __LINE__, __func__);
room->NotifyUiUpdate();
}
void Car::GetOn(Human* passenger)
{
if (later_removed_) {
return;
}
if (meta->int_param2 <= 0) {
abort();
}
if (meta->int_param2 <= passengers_.size()) {
return;
}
if (passengers_.find(passenger) != passengers_.end()) {
return;
}
if (passenger->GetCar()) {
return;
}
for (auto hum : passengers_) {
if (hum->team_id != passenger->team_id) {
return;
}
}
int seat = AllocSeat();
if (seat < 0) {
return;
}
passengers_.insert(passenger);
if (!driver_) {
driver_ = passenger;
}
passenger->SetCar(this);
passenger->SetSeat(seat);
passenger->SetPos(GetPos());
{
MetaData::Buff* buff_meta = MetaMgr::Instance()->GetBuff
(driver_ == passenger ? DRIVER_BUFFID : PASSENGER_BUFFID);
if (buff_meta) {
passenger->AddBuff(passenger, buff_meta, 1);
}
}
{
MetaData::Buff* buff_meta = MetaMgr::Instance()->GetBuff(meta->i->buffid());
if (buff_meta) {
passenger->AddBuff(passenger, buff_meta, 1);
}
}
passenger->CancelAction();
room->frame_event.AddCarChg(passenger);
SyncAroundPlayers(__FILE__, __LINE__, __func__);
}
int Car::AllocSeat()
{
int seat = -1;
for (int i = 0; i < meta->int_param2; ++i) {
bool found = false;
for (auto hum : passengers_) {
if (hum->GetSeat() == i) {
found = true;
break;
}
}
if (!found) {
seat = i;
break;
}
}
return seat;
}