#pragma once #include #include #include "frameevent.h" #include "framemaker.h" #include "gridservice.h" #include "mapservice.h" #include "gasdata.h" #include "pvedata.h" namespace cs { class SMJoinedNotify; } class Entity; class RoomEntity; class MoveableEntity; class Obstacle; class RoomObstacle; class Bullet; class Human; class Player; class Android; class Car; class Hero; class Incubator; class Team; class AirDrop; class AirRaid; struct BornPoint; class MapInstance; struct RoomInitInfo; struct FrameEventData; class SandTable; struct Plane { glm::vec3 start_point; glm::vec3 end_point; glm::vec3 dir; glm::vec3 curr_pos; }; struct CarObject { int car_id = 0; glm::vec3 pos; bool taken = false; }; enum RoomSwitch_e { kRoomSwitchDisableMove = 0, kRoomSwitchDisableUseSkill, kRoomSwitchDisableUseItem, kRoomSwitchDisableShot, }; typedef void (*FrameCallCb)(void*); struct FrameCallNode; class MatchTeam; class Room { public: FrameEvent frame_event; FrameEventData* frame_event_data = nullptr; FrameMaker frame_maker; a8::XTimer xtimer; Plane plane; f8::Attacher timer_attacher; a8::Attacher xtimer_attacher_; GridService* grid_service = nullptr; MapService* map_service = nullptr; std::shared_ptr map_instance; bool debug_trace = false; bool added_to_over_room = false; glm::vec3 last_player_jump_pos; std::map mine_objects; const mt::PveGeminiMode* pve_mode_meta = nullptr; const mt::PveGemini* pve_instance = nullptr; int pve_human_num = 0; PveData pve_data; bool stop_world = false; //target_uniid, frameno std::map report_bullet_hash; a8::XTimerWp game_over_timer; #ifdef DEBUG std::map debug_params; #endif ~Room(); void InitData(RoomInitInfo& init_info); void Init(); void UnInit(); void Update(int delta_time); inline long long GetFrameNo() { return frameno_; } long long GetBattleStartFrameNo() { return battle_start_frameno_; } bool IsGameOver() { return game_over_; } bool IsGameTimeOut() { return game_timeout_; } bool IsForceOver() { return force_over_; } const GasData& GetGasData() { return gas_data_; } RoomType_e GetRoomType() { return room_type_; } RoomMode_e GetRoomMode() { return room_mode_; } long long GetRoomUuid() { return room_uuid_; } int GetRoomIdx() { return room_idx_; } std::string GetMapTplName() { return map_tpl_name_; } const mt::Map* GetMapMeta() { return map_meta_; } bool IsBattleStarting() { return battle_starting_; }; bool IsPveRoom(); bool IsDestoryRoom(); bool IsSurvivalRoom(); bool IsNewBieRoom(); int GetPlayerNum(); int GetHumanNum(); int AliveCount(); long long AliveCountChgFrameNo() { return alive_count_chged_frameno_; }; inline int RealAliveCount() { return alive_human_hash_.size(); } Player* GetPlayerByAccountId(const std::string& accountid); Player* GetPlayerByUniId(int uniid); Entity* GetEntityByUniId(int uniid); Creature* GetCreatureByUniId(int uniid); Human* GetHumanByUniId(int uniid); int GetRealPlayerNum() { return accountid_hash_.size();} void OnEnterNewWave(int wave); Player* NewPlayer(); void AddPlayer(Player* hum, std::shared_ptr init_born_point = nullptr, bool no_matchteam = false); Human* FindEnemy(Human* hum, float range); Creature* FindEnemy(Creature* c, float range); void AddTeam(class MatchTeam* team); void RemoveObjectLater(RoomEntity* entity); void RemoveObjectLater(RoomObstacle* entity); void FillSMJoinedNotify(Player* self_hum, cs::SMJoinedNotify& msg); void TraversePlayerList(std::function func); void TraverseHumanList(std::function func); void TraverseEntityList(std::function func); void TraverseAlivePlayers(std::function func); void BroadcastDebugMsg(const std::string& debug_msg); void ScatterDrop(const glm::vec3& center, int drop_id); void DropItem(const glm::vec3& pos, int item_id, int item_count, int item_lv); void DropItemEx(const glm::vec3& born_pos, const glm::vec3& pos, int item_id, int item_count, int item_lv, bool show_anim); int CreateLoot(int equip_id, const glm::vec3& pos, int count, int equip_lv); int CreateLootEx(int equip_id, const glm::vec3& born_pos, const glm::vec3& pos, int count, int equip_lv, bool show_anim); int CreateBullet(Creature* sender, Creature* passenger, const mt::Equip* weapon_meta, const mt::Equip* bullet_meta, const mt::Skill* skill_meta, glm::vec3 pos, glm::vec3 dir, float fly_distance, long long weapon_uniid, int trace_target_id, int hand, a8::XTimerWp keep_shot_animi_timer_ptr, float shot_animi_time, int weapon_buff_id, std::shared_ptr> reporter_list); Car* CreateCar(Human* driver, int car_uniid, const mt::Equip* meta, const glm::vec3& pos, int team_id); Hero* CreateHero(Creature* master, const mt::Hero* meta, const glm::vec3& pos, const glm::vec3& dir, int team_id); void OnHumanDie(Human* hum); void OnHumanRevive(Human* hum); bool OverBorder(const glm::vec3& pos, float radius); Human* GetWatchWarTarget(Human* hum); bool BattleStarted(); int GetTeamNum(); Team* GetTeam(int team_id); int GetAliveTeamNum(); Team* GetAliveTeam(); void TraverseTeams(std::function cb); bool CanJoin(const std::string& accountid, RoomType_e self_roomm_type, RoomMode_e self_room_mode, int self_proto_version, int self_channel, int init_map_id, const cs::CMJoin& msg); bool CanJoin(class MatchTeam* team); void OnPlayerOffline(Player* hum); void FillSMUiUpdate(cs::SMUiUpdate& msg); void NotifyUiUpdate(); void UpdateCarObject(int old_uniid, int new_uniid, glm::vec3 pos); void TakeOnCarObject(int car_uniid); void TakeOffCarObject(int car_uniid, glm::vec3 pos); int CreateAndTakeonCar(int car_id, glm::vec3 pos); bool HaveMyTeam(const std::string& team_uuid); long long GetGasInactiveTime(); void CheckPartObjects(Human* testa = nullptr, Human* testb = nullptr); bool RuningInTimer(); Human* GetOneCanEnableAndroid(); void GetCanEnableAndroids(std::vector& humans, size_t num); void InstallCheckAutoDieTimer(Human* hum); Player* GetOneAlivePlayer(); void GetAlivePlayers(std::vector& humans, size_t num); int GetCanShuaNum(int shua_num); void RemoveRescue(Human* hum); void NotifyCountdown(const std::string& msg, int time); void NotifySysPiao(const std::string& msg, int color, int duration); int GetOnlinePlayerNum(); RoomObstacle* CreateObstacle(int id, float x, float y, float z, std::shared_ptr init_args = nullptr); int AllocUniid(); Incubator* GetIncubator() { return incubator_;}; void GetPartObjectWatchList(Entity* entity, std::vector& watch_list); void SetInfiniteBulletMode(); bool IsInfiniteBulletMode() { return infinite_bullet_mode_; }; void AddToPostBattleAutoFreeList(a8::XTimerWp timer); bool CanAddObstacle(const glm::vec3& pos, int obstacle_id); void AddTask(int task_uniid, ITask* task); void RemoveTask(int task_uniid); const mt::AirLine* GetAirLine() { return airline_; } int GetPolyExtFlag(int poly_idx); size_t GetRoomMaxPlayerNum(); bool RandomSafeAreaPoint(glm::vec3& point); bool FindWalkablePointWithOutHouse(const glm::vec3& center, int try_count, int step, glm::vec3& out_point); void AddReportBullet(int bullet_uniid); bool IsDestorying() { return destorying_; } void AddFrameCall(FrameCallCb cb, void* context); void SetVictoryTeam(Team* team) { victory_team_ = team;}; Team* GetVictoryTeam() { return victory_team_;}; int GetReportRoomMode(); int GetPvpMatchMode(); void ForceOver(); bool SupportSandTable(); std::shared_ptr GetSandTable() { return sand_table_; } bool IsSandTableRoom(); void LockRoom() { lock_room_ = true; } void CombineTeam(); void FillTeam(); bool HasRoomSwitch(int tag); void OpenRoomSwitch(int tag); void CloseRoomSwitch(int tag); void NotifyNewsTicker(int msg_type, std::vector msg_content); std::shared_ptr GetAirRaid() { return air_raid_; } private: void ShuaAndroid(); void ShowAndroid(Human* target, int num); void CreateAndroid(int android_num); void UpdateGas(); void UpdateGasInactive(); void UpdateGasInactivePvp(); void UpdateGasInactivePve(); void UpdateGasInactiveNewBie(); void UpdateGasWaiting(); void UpdateGasMoving(); void UpdateGasJump(); bool GenSmallCircle(); void MatchTeam(Human* hum); void ShuaPlane(); Team* NewTeam(); RoomObstacle* InternalCreateObstacle(int id, float x, float y, float z, std::function on_precreate, std::shared_ptr init_args = nullptr); void AddObjectLater(RoomEntity* entity); void OnGameOver(); void RandRemoveAndroid(); std::shared_ptr AllocBornPoint(Human* hum); std::shared_ptr GetBornPoint(int point_uniid); void CreateSpawnPoints(); void CreateWorldObjects(); void IncBornPointHumanNum(std::shared_ptr point, Human* hum); void DecBornPointHumanNum(std::shared_ptr point, Human* hum); void SecondRandPoint(); void NotifyGameStart(); void EnableHuman(Human* hum); void DisableHuman(Human* hum); void ShuaAndroidTimerFunc(); void DieAndroidTimerFunc(); void ProcShuaAndroid(int shua_time, int shua_num); void ProcDieAndroid(int die_time, int die_num); void CheckAutoDie(Human* hum, int autodie_time, int autodie_distance, int check_times); bool HasPlayerInRound(const glm::vec3& pos, float rad); void ProcDisableHuman(); void OnHumanGridChg(Human* target); void ShuaGridRound(Human* target); void GetAliveHumans(std::vector& alive_humans, size_t num, Human* exclude_hum); void GetCanAutoDieHumans(std::vector& alive_humans, size_t num, Human* exclude_hum); void CheckAliveHuman(Human* hum, std::vector& alive_humans); void AddToEntityHash(Entity* entity); void AddToHumanHash(Human* hum); void AddToAliveHumanHash(Human* hum); void AddToMoveableHash(MoveableEntity* entity); void AddToAccountHash(Player* hum); void AddToLaterAddHash(RoomEntity* entity); void AddToRemovedRobotHash(Human* hum); void RemoveFromEntityHash(Entity* entity); void RemoveFromMoveableHash(MoveableEntity* entity); void RemoveFromHuamnHash(Human* hum); void RemoveFromAliveHumanHash(Human* hum); void RemoveFromLaterAddHash(RoomEntity* entity); void AddPlayerPostProc(Player* hum); void CombineTeamBornPoint(); void ForceSetBornPoint(Human* hum, std::shared_ptr born_point); std::shared_ptr ForceTakeBornPoint(Human* hum, std::shared_ptr reserve_born_point); void NewBieRoomStart(); bool CanAddToScene(Human* hum); void SyncFrameData(); void CheckShowHand(); void ShowHand(); void ShuaLastGas(); void InitAndroidAI(); void ForwardGasRing(int n); void InternalRemoveObjectLater(Entity* entity, a8::Attacher& entity_xtimer_attacher); void OnBattleStart(); void ClearPostBattleAutoFreeList(); void OnAddHuman(Human* hum); #ifdef DEBUG void InitDebugInfo(); void UnInitDebugInfo(); #endif bool IsAllRealDead(); void AutoJump(); void UpdateFrameCall(); private: bool destorying_ = false; std::vector poly_ext_datas_; int room_idx_ = 0; RoomMode_e room_mode_ = kPvpMode; long long room_uuid_ = 0; const mt::Map* map_meta_ = nullptr; std::string map_tpl_name_; RoomType_e room_type_ = RT_NewBrid; GasData gas_data_; long long frameno_ = 0; long long battle_start_frameno_ = 0; bool game_timeout_ = false; bool game_over_ = false; long long game_over_frameno_ = 0; int elapsed_time_ = 0; int alive_count_ = 0; long long alive_count_chged_frameno_ = 0; int human_alive_count_ = 0; const mt::AirLine* airline_ = nullptr; int level0room_born_point_uniid_ = 0; int level1room_born_point_uniid_ = 0; bool show_handed_ = false; int creator_game_times_ = 0; int creator_register_time_ = 0; int creator_proto_version_ = 0; int creator_channel_ = 0; bool force_entry_newbie_room_ = false; bool is_newbie_room_ = false; a8::XTimerWp battle_report_timer_; int current_teamid_ = 0; int current_uniid_ = FIXED_OBJECT_MAXID; std::set refreshed_robot_set_; std::map team_hash_; std::map combineable_team_hash_; std::map accountid_hash_; std::map moveable_hash_; std::map uniid_hash_; std::map later_add_hash_; std::map human_hash_; std::map alive_human_hash_; std::map alive_player_hash_; std::map last_human_hash_; std::map> born_point_hash_; std::map task_hash_; std::map car_hash_; std::map removed_robot_hash_; std::vector post_battle_auto_free_list_; a8::XTimerWp auto_jump_timer_; Incubator* incubator_ = nullptr; std::shared_ptr sand_table_; bool infinite_bullet_mode_ = false; bool battle_starting_ = false; std::shared_ptr air_drop_; std::shared_ptr air_raid_; FrameCallNode* top_node_ = nullptr; FrameCallNode* bot_node_ = nullptr; FrameCallNode* work_node_ = nullptr; Team* victory_team_ = nullptr; bool force_over_ = false; bool lock_room_ = false; long long room_switch_ = 0; friend class Incubator; friend class Team; };