diff --git a/server/gameserver/car.cc b/server/gameserver/car.cc index 04ed96e6..e4763ef9 100644 --- a/server/gameserver/car.cc +++ b/server/gameserver/car.cc @@ -139,6 +139,9 @@ void Car::GetOn(Human* passenger) if (later_removed_) { return; } + if (!CanOn(passenger)) { + return; + } if (meta->_int_param2 <= 0) { A8_ABORT(); } @@ -577,3 +580,14 @@ void Car::Update(int delta_time) UpdateSkill(); } } + +bool Car::CanOn(Human* hum) +{ + return special_operators_.empty() || + special_operators_.find(hum->GetUniId()) != special_operators_.end(); +} + +void Car::SetSpecialOperators(std::set& special_operators) +{ + special_operators_ = special_operators; +} diff --git a/server/gameserver/car.h b/server/gameserver/car.h index c1404c3e..8fc9ee4c 100644 --- a/server/gameserver/car.h +++ b/server/gameserver/car.h @@ -49,6 +49,8 @@ class Car : public Creature void OnKillTarget(Creature* target); void SetShotDir(const glm::vec3& dir) { curr_shot_dir_ = dir; }; bool IsSingle(); + bool CanOn(Human* hum); + void SetSpecialOperators(std::set& special_operators); private: int AllocSeat(); @@ -67,6 +69,7 @@ class Car : public Creature int cur_buff_idx_ = -1; float cur_oil_ = 0; glm::vec3 curr_shot_dir_ = GlmHelper::ZERO; + std::set special_operators_; friend class PBUtils; }; diff --git a/server/gameserver/commands.cc b/server/gameserver/commands.cc index 88ba1b7d..6f7b568a 100644 --- a/server/gameserver/commands.cc +++ b/server/gameserver/commands.cc @@ -315,10 +315,11 @@ void Player::_CMExecCommand(f8::MsgHdr& hdr, const cs::CMExecCommand& msg) int car_uniid = room->AllocUniid(); glm::vec3 pos = GetPos().ToGlmVec3(); Car* c = room->CreateCar(nullptr, - car_uniid, - equip_meta, - pos, - 0); + car_uniid, + equip_meta, + pos, + 0, + nullptr); if (c) { #if 0 CarObject car; diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 50c779c2..bd5f6ef1 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -2089,12 +2089,12 @@ void Human::DoGetOnWithLoot(Loot* entity) GetCar()->GetDown(this); } Car* car = room->CreateCar( - this, - entity->GetUniId(), - item_meta, - entity->GetPos().ToGlmVec3(), - team_id - ); + this, + entity->GetUniId(), + item_meta, + entity->GetPos().ToGlmVec3(), + team_id, + nullptr); car->GetOn(this); #ifdef DEBUG a8::XPrintf("DoGetOnWithLoot uniid:%d car_uniid:%d\n", {car->GetUniId(), car->car_uniid}); diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index b9e6988d..06fed3a9 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -702,7 +702,8 @@ Car* Room::CreateCar(Human* driver, int car_uniid, const mt::Equip* item_meta, const glm::vec3& pos, - int team_id) + int team_id, + std::set* special_operators) { Car* car = EntityFactory::Instance()->MakeCar(AllocUniid()); car->car_uniid = car_uniid; @@ -711,6 +712,9 @@ Car* Room::CreateCar(Human* driver, car->team_id = team_id; car->GetMutablePos().FromGlmVec3(pos); car->SetAttackDir(GlmHelper::DONW); + if (special_operators) { + car->SetSpecialOperators(*special_operators); + } car->Initialize(); AddToEntityHash(car); AddToMoveableHash(car); @@ -3008,7 +3012,8 @@ void Room::CreateWorldObjects() car_uniid, equip_meta, pos, - 0); + 0, + nullptr); if (c) { CarObject car; car.car_id = equip_meta->id(); diff --git a/server/gameserver/room.h b/server/gameserver/room.h index cc7cbca3..031e56e5 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -172,7 +172,8 @@ public: int car_uniid, const mt::Equip* meta, const glm::vec3& pos, - int team_id); + int team_id, + std::set* special_operators); Hero* CreateHero(Creature* master, const mt::Hero* meta, const glm::vec3& pos, diff --git a/server/tools/protobuild/cs_proto.proto b/server/tools/protobuild/cs_proto.proto index ce747d7c..921912b9 100755 --- a/server/tools/protobuild/cs_proto.proto +++ b/server/tools/protobuild/cs_proto.proto @@ -510,6 +510,7 @@ message MFCarFull repeated MFEffect effect_list = 18; //特效列表 optional int32 team_id = 19; //队伍id repeated MFSkill skill_list = 20; //技能列表 + repeated int32 special_operators = 21; //指定能上载具的玩家uniid,空的话则不限 /* 乘客列表(包含驾驶员) !!!注意这里只返回客户端必要的用于显示玩家外观的信息而不是全量信息