require("game.scene.SceneManager") require("game.particalEffect.ParticleManager") require("game.scene.SceneLoadView") require("game.proto.121.Require121") require("game.scene.ChangeSceneMovie") require("game.scene.ChangeSceneMovieRT") SceneController=SceneController or BaseClass(BaseController) local SceneController = SceneController local GlobalEventSystem = GlobalEventSystem local SceneManager = SceneManager local lua_viewM = lua_viewM local print = print local math_floor = math.floor function SceneController:__init() SceneController.Instance = self OperateManager.New() MainCamera.New() self.scene_mgr = SceneManager:getInstance() self.scene = Scene:getInstance() self:RegisterAllProtocals() self:RegisterAllEvents() Runner.Instance:AddRunObj(self, 1) Runner.Instance:AddLateRunObj(self) --用于计算持续无缝切换的次数,超过三次则强制执行正常切换场景 self.continuity_noloading_times = 0 --是否忽略上面那个参数的计数 self.ignore_count_loading_time = false self.frame_index = 0 end function SceneController:__delete() end function SceneController:RegisterAllProtocals() --[[@tips 客户端加载完场景,通过NOTICE_SCENE_LOAD_WILL_COMPLETE事件请求12035协议,通知服务端场景切换完成; 服务端收到12035协议,再广播13009角色状态; 客户端收到13009协议,最终才派发SCENE_LOAD_VIEW_COMPLETE事件,通知业务逻辑场景切换完成。 ]] self:RegisterProtocal2(12001, SceneController.handler12001) --走路 self:RegisterProtocal2(12002, SceneController.handler12002) --加载场景信息 self:RegisterProtocal2(12003, SceneController.handler12003) --通知场景玩家有某个玩家进入 self:RegisterProtocal2(12004, SceneController.handler12004) --有玩家离开场景 self:RegisterProtocal2(12005, SceneController.handler12005) --切换到新场景 0服务器传送 1小飞鞋 2世界传送(到出生点) 3传统传送门 4任意城市传送门 self:RegisterProtocal2(12006, SceneController.handler12006) --清除场景对象 self:RegisterProtocal2(12007, SceneController.handler12007) --怪物进入 self:RegisterProtocal2(12008, SceneController.handler12008) --场景对象移动 self:RegisterProtocal2(12009, SceneController.handler12009) --角色血量变化 self:RegisterProtocal2(12010, SceneController.handler12010) --场景角色属性更改 self:RegisterProtocal2(12011, SceneController.handler12011) --9宫格加载用户 self:RegisterProtocal2(12012, SceneController.handler12012) --9宫格加载场景对象 self:RegisterProtocal2(12013, SceneController.handler12013) --广播玩家进入飘窗提示 self:RegisterProtocal(12014, "handler12014") self:RegisterProtocal(12015, "handler12015") self:RegisterProtocal(12016, "handler12016")--通用状态变更通知 self:RegisterProtocal(12020, "handler12020") self:RegisterProtocal(12023, "handler12023") self:RegisterProtocal(12025, "handler12025") -- 玩家动作播放 self:RegisterProtocal(12027, "handler12027") -- 玩家动作播放 self:RegisterProtocal(12070, "handler12070") self:RegisterProtocal(12071, "handler12071") self:RegisterProtocal(12072, "handler12072") self:RegisterProtocal(12073, "handler12073") self:RegisterProtocal(12075, "handler12075") self:RegisterProtocal(12076, "handler12076") self:RegisterProtocal(12078, "handler12078") self:RegisterProtocal(12080, "handler12080") self:RegisterProtocal(12081, "handler12081") self:RegisterProtocal(12082, "handler12082") self:RegisterProtocal(12083, "handler12083") self:RegisterProtocal(12084, "handler12084") self:RegisterProtocal(12085, "handler12085") self:RegisterProtocal(12086, "handler12086") --npc self:RegisterProtocal(12100, "handler12100") --动态npc信息 self:RegisterProtocal(12103, "handler12103") --场景中动态改变NPC状态 --场景掉落 self:RegisterProtocal(12017, "handler12017") --物品包掉落 self:RegisterProtocal(12018, "handler12018") --玩家上线后能看到身边周围的怪物掉落 self:RegisterProtocal(12019, "handler12019") --场景/九宫格物品消失,相对于其他玩家 self:RegisterProtocal(12024, "handler12024") --攻防双方都飘字的血量变化 self:RegisterProtocal(12034, "handler12034") --请求超链接坐标切场景 self:RegisterProtocal(12030, "handler12030") --改变动态区域属性 self:RegisterProtocal(12032, "handler12032") --改变动态特效属性 self:RegisterProtocal(12033, "handler12033") --小飞鞋 self:RegisterProtocal(12022, "handler12022") --boss归属 self:RegisterProtocal(12089, "handler12089") --场景活动标识改变 self:RegisterProtocal(12090, "handler12090") --怪物非常用属性修改 self:RegisterProtocal(12099, "handler12099") --移动协议错误通知(0非错误[实际上不通知],1错误目标场景,2CD时间,3距离超限) end --[[ 功能:游戏状态机更新 其他. 作者:zsm ]] function SceneController:Update(now_time, elapse_time) -- --对于服务端战斗场景,每帧都创建一个怪 -- local delay_num = SceneManager.Instance:GetDelayMonsterNum() -- if delay_num > 0 and (self.create_delay_time == nil or now_time - self.create_delay_time > 0.1) then -- SceneManager.Instance:AddDelaydMonsterVo() -- self.create_delay_time = now_time -- end -- --每帧创建一个玩家 -- local delay_role_num = SceneManager.Instance:GetDelayRoleNum() -- if delay_role_num > 0 and (self.create_role_delay_time == nil or now_time - self.create_role_delay_time > 0.1) then -- SceneManager.Instance:AddDelayRoleVo() -- self.create_role_delay_time = now_time -- end -- self.scene:Update(now_time, elapse_time) self.frame_index = self.frame_index + 1 -- if G_DEBUG_UPDATE_STEP and self.frame_index % G_DEBUG_UPDATE_STEP ~= 0 then -- return -- end if self.frame_index % (lua_viewM:GetFrameUpdateCount() + 3) == 0 then --对于服务端战斗场景,每帧都创建一个怪 self.scene_mgr:AddDelaydMonsterVo() end if self.scene_mgr:IsMainCityorYieldScene() then if self.frame_index % (lua_viewM:GetFrameUpdateCount() + 13) == 0 then self.scene_mgr:AddDelayRoleVo() end else --每帧创建一个玩家 self.scene_mgr:AddDelayRoleVo() end self.scene:Update(now_time, elapse_time) end function SceneController:LoadSceneInfoRequest(scene_id) -- 先请求NPC列表再请求12002 self:SendFmtToGame(12100, "i", scene_id or SceneManager.Instance:GetSceneId()) end function SceneController:handler12001() local self = SceneController.Instance local rx,ry,role_id,fly_flag = self:ReadFmt("hhlc") local args_1, args_2, args_3, args_4 = 0 if fly_flag ~= MOVE_TYPE.NORMOL_MOVE then --非正常走路 args_1, args_2, args_3, args_4 = self:ReadFmt("hhhh") end -- if fly_flag == 4 then -- print(">>>>>> TASK_JUMP >>> ", args_1, args_2, args_3, args_4) -- end -- if fly_flag == 0 then -- print(">>>>>> NORMOL_MOVE >>> ", args_1, args_2, args_3, args_4) -- end if role_id ~= RoleManager.Instance:GetMainRoleId() then self.scene:RoleMove(role_id, rx, ry, fly_flag, args_1, args_2, args_3, args_4) end end -----------------加载场景信息反馈(12002)------------ function SceneController:handler12002() local self = SceneController.Instance print("----------handler12002---------") if SceneManager.Instance:IsSceneStart() then return end SceneManager.Instance:ClearAllVo() --处理传送阵和NPC,里面会判断是否需要重新加载 SceneManager.Instance:LoadNpcsAndDoors() --处理场景内的跳点 SceneManager.Instance:LoadJumpPoints() --处理玩家 SceneManager.Instance:ResetCachedRoleList() --重置缓存队列 local add_num = self:ReadFmt("h") for i = 1, add_num do self:handler12003() end --处理怪物 add_num = self:ReadFmt("h") for i = 1, add_num do self:handler12007() end --处理其他场景对象 add_num = self:ReadFmt("h") for i = 1, add_num do self:handler12014() end --假人 add_num = self:ReadFmt("h") for i = 1, add_num do self:handler12015() end --请求动态区域信息 self:handler12030() --场景开始流程 SceneManager.Instance:SceneStart() --场景中的怪物类型,如果没有加载过,就要 -- local scene_id = SceneManager.Instance:GetSceneId() -- local monster_types = SceneManager.Instance:GetMonsterTypeInScene(scene_id) -- if monster_types then -- for _, type_vo in pairs(monster_types) do -- SceneManager.Instance:AddMonsterType(type_vo) -- end -- end --请求上线时要显示的掉落 self:SendFmtToGame(12018) if Scene.Instance:IsProgressLoadFinish() then --通知服务器完成了场景切换 self:SendFmtToGame(12035) GlobalEventSystem:Fire(SceneEventType.REQUEST_DYNAMIC_EFFECT) end --通知npc加载完成 GlobalEventSystem:Fire(EventName.NPC_LOAD_FINISH) --无缝加载之后的同步坐标,服务端限制了只能在12002协议之后生效 if self.is_no_loading_scene then local function on_delay( ) self:SendFmtToGame(12035) if not SceneManager.Instance:IsOneTowerScene() then local pos_x, pos_y, angel = SceneManager:getInstance():GetCacheMainRolePos( ) if pos_x and pos_y and angel then GlobalEventSystem:Fire(SceneEventType.MOVEREQUEST, pos_x, pos_y, MOVE_TYPE.BLINK) SceneManager:getInstance():ResetCacheMainRolePos( ) end end end on_delay() end end --请求切换场景 function SceneController:requestChangeScene( scene_id, call_back_type, send_type, pos_x, pos_y) if self.fly_shoe_event_id or self.fly_shoe__delay_event_id then return end pos_x = pos_x or 0 pos_y = pos_y or 0 pos_x = pos_x < 0 and 0 or math.floor(pos_x) pos_y = pos_y < 0 and 0 or math.floor(pos_y) self.scene_mgr:SetCurrentReqChangeSceneId(scene_id) self:SendFmtToGame(12005, "iicchh", 0,scene_id, call_back_type or 0, send_type or 0, pos_x, pos_y) end --脱离卡死加载场景,由客户端触发 function SceneController:OutOfStuck() local func = function () local scene_id = SceneManager.Instance:GetSceneId() OperateManager.Instance:StopMove(true) SceneManager.Instance:ClearAllVo() self.scene:ClearScene(false) self.scene:CreateMainRole() local main_role = Scene.Instance:GetMainRole() local vo = ConfigItemMgr.Instance:GetSceneItem(scene_id) main_role:SetRealPos(vo.x, vo.y,true) GlobalEventSystem:Fire(SceneEventType.OPEN_SCENE_LOAD_VIEW) self:SendFmtToGame(12001, "ihhchhhh", scene_id,Util.Int(vo.x),Util.Int(vo.y),flag or 0,Util.Int(vo.x), Util.Int(vo.y), Util.Int(start_fly_x), Util.Int(start_fly_y)) self:LoadSceneInfoRequest() end SceneManager.Instance:ShowPreChangeSceneView( func ) end function SceneController:handler12003() local self = SceneController.Instance local role_vo = RoleVo.New() role_vo:ReadFromProtocal() local grid_x, grid_y = role_vo.pos_x / SceneObj.LogicRealRatio.x, role_vo.pos_y / SceneObj.LogicRealRatio.y if self.scene_mgr:IsBlockXY(grid_x, grid_y) then local end_pos = SourceOperateMove.FindNoBlockPos(co.TableXY(grid_x, grid_y)) role_vo.pos_x = end_pos.x * SceneObj.LogicRealRatio.x role_vo.pos_y = end_pos.y * SceneObj.LogicRealRatio.y if role_vo.role_id == RoleManager.Instance:GetMainRoleId() then local main_role = self.scene.main_role if main_role then main_role:SetRealPos(role_vo.pos_x,role_vo.pos_y,true) main_role:SetGhostMode(false) end --角色复活,刷新左上角血量 GlobalEventSystem:Fire(EventName.MAINROLE_RESURGENCE,role_vo.role_id,role_vo.hp,role_vo.maxHp) end end SceneManager.Instance:AddRoleVo(role_vo, true) end function SceneController:handler12004() local self = SceneController.Instance local role_id = self:ReadFmt("l") SceneManager.Instance:DeleteRoleVo(role_id) end function SceneController:handler12005() if not SceneController.Instance.is_game_started then return end local self = SceneController.Instance local instance_id, --场景实例ID(int32) pos_x, --进入场景的X坐标(int16) pos_y, --进入场景的Y坐标(int16) error_code, --错误信息(int32) dun_id, call_back_type, send_type = self:ReadFmt("ihhiicc") print("----------handler12005---------",call_back_type, instance_id, SceneManager.Instance.last_scene_id, dun_id, pos_x, pos_y) self:RemoveSendFmtCheckout(12002)--移除12002协议超时检测 --防止同时刻因为请求了小飞鞋切场景,然后服务器还返回的,导致客户端正常切场景失败 if instance_id == 0 and error_code == 1200017 and self.fly_shoe_event_id then ErrorCodeShow(error_code) return end --无尽回廊 爬塔时切换场景不要关闭其他界面 local dun_tower_not_close_all_view = false if SceneManager.Instance:IsOneTowerNormalDungeon(dun_id) then if SceneManager.Instance:IsOneTowerNormalDungeon() then dun_tower_not_close_all_view = true end end TaskModel:getInstance().proto_count = 0 self.last_send_pos = false if self.fly_shoe_event_id then GlobalTimerQuest:CancelQuest(self.fly_shoe_event_id) self.fly_shoe_event_id = nil end if self.fly_shoe__delay_event_id then GlobalTimerQuest:CancelQuest(self.fly_shoe__delay_event_id) self.fly_shoe__delay_event_id = nil end if not dun_tower_not_close_all_view then EventSystem.Fire(GlobalEventSystem,EventName.CLOSE_MAPPANEL_VIEW) EventSystem.Fire(GlobalEventSystem,EventName.CLOSE_ALL_VIEW) end local is_no_loading_scene = self.scene_mgr:NoLoadingViewScene(instance_id) if is_no_loading_scene and not SceneManager.Instance:IsOneTowerScene() then self.scene_mgr:SetCacheMainRolePos() end self.is_no_loading_scene = is_no_loading_scene self.temp_instance_id = instance_id if instance_id ~= 0 and (send_type or self.scene_mgr:IsDungeonScene() or self.scene_mgr:IsDungeonScene(instance_id)) and not is_no_loading_scene then --使用飞鞋传送 GlobalEventSystem:Fire(EventName.STOPAUTOFIGHT, false, true) local function delay_method( ) local main_role = self.scene:GetMainRole() if main_role then -- if (send_type == 3 or send_type == 4) then -- main_role:DoTransfer(nil, 2, nil) -- else if self.temp_instance_id and self.temp_instance_id ~= 0 then main_role:DoFlyShoeEffect(nil, 2, nil, true) end --end end self.fly_shoe__delay_event_id = nil end local do_fly = true --静默重连,不需要飞行 if UserMsgAdapter and UserMsgAdapter.Instance:GetIsAutoConnecting( ) then do_fly = false end if do_fly then self.fly_shoe__delay_event_id = setTimeout(delay_method, 0.01)--不延迟一下的话不会飞,只会跳一下(偶发) end local function fly_end( ) if is_no_loading_scene and error_code == 1 then --ChangeSceneMovie:getInstance():TryOpen() end self:ChangeScene(self.temp_instance_id,pos_x,pos_y,dun_id, error_code) self.fly_shoe_event_id = nil end local time = (send_type == 3 or send_type == 4) and Config.otherFightInfo.jump_action_time["transferout"] or Config.otherFightInfo.jump_action_time["flyup"] if not self.has_enter_game then self.has_enter_game = true time = 0.01 end self.fly_shoe_event_id = setTimeout(fly_end, time) if AutoFightManager:getInstance().next_fly_pos then AutoFightManager:getInstance().next_fly_pos.x = pos_x AutoFightManager:getInstance().next_fly_pos.y = pos_y end if SceneManager.Instance:IsOneTowerDungeon(dun_id) then--爬塔副本连续挑战需要保存副本ID SceneManager.Instance:SetCurrDunId(dun_id) end else if is_no_loading_scene and error_code == 1 then --ChangeSceneMovie:getInstance():TryOpen() end AutoFightManager:getInstance().next_fly_pos = nil self:ChangeScene(self.temp_instance_id,pos_x,pos_y,dun_id, error_code) end end function SceneController:ChangeScene(instance_id,pos_x,pos_y,dun_id, error_code) -- print("tanar: [SceneController 404]=> instance_id: ",instance_id) -- print("tanar: [SceneController 405]=> SceneManager.Instance.last_scene_id: ",SceneManager.Instance.last_scene_id) if instance_id ~= 0 then self.cache_move_error_type = {} local main_role_vo = RoleManager.Instance.mainRoleInfo main_role_vo.pos_x = pos_x main_role_vo.pos_y = pos_y OperateManager.Instance:StopMove(true) --, 先清掉当前场景的操作包,避免继续移动寻路 local last_id = SceneManager.Instance:GetSceneId() SceneManager.Instance:SetCurrentSceneId(instance_id) SceneManager.Instance:SetCurrDunId(dun_id) if self.change_scene_event_id then GlobalTimerQuest:CancelQuest(self.change_scene_event_id) self.change_scene_event_id = nil end GlobalEventSystem:Fire(SceneEventType.OPEN_SCENE_LOAD_VIEW) SceneManager.Instance:ClearAllVo() --必须要先移除vo再移除场景对象元素 派发dispose方法来移除所有针对场景元素的引用 if SceneManager.Instance.last_scene_id ~= instance_id then local delay_fun = function () self.scene:ClearScene() self.scene:SceneLoadingEnter(instance_id) --预加载,申请12002切换场景 self.scene:CreateMainRole() self.scene:ChangeMainRoleScale() -- if AutoFightManager:getInstance().next_fly_pos -- or self.scene_mgr:IsDungeonScene(instance_id) -- or self.scene_mgr:IsDungeonScene(self.scene_mgr:GetLastSceneId())then -- if self.scene.main_role then -- self.scene.main_role:SetModelHideFlag(SceneObj.ModelHideFlag.Fly, true) -- end -- end GlobalEventSystem:Fire(SceneEventType.SCENE_CHANGED, instance_id) end self.change_scene_event_id = setTimeout(delay_fun, 0.001) else local delay_fun = function () --同场景传送时不用清传送门和NPC self.scene:ClearScene(false) self.scene:SceneLoadingEnter(instance_id) self.scene:CreateMainRole() end self.change_scene_event_id = setTimeout(delay_fun, 0.001) GlobalEventSystem:Fire(SceneEventType.SCENE_REENTER, instance_id) end else if instance_id == 0 then GlobalEventSystem:Fire(EventName.PLAY_MAINUI_MOVIE_CENTER_EVENT) ErrorCodeShow(error_code) if error_code == 1200011 then AutoFightManager:getInstance():FindVoCallTypeFun(call_back_type) end else Message.show(error_str,"场景配置不存在") end end end --服务器通知清除场景对象 function SceneController:handler12006() local self = SceneController.Instance --竞技场不通过服务器清除场景对象 if SceneManager.Instance:IsPkRankFightScene() then return end local instance_id = self:ReadFmt("i") local vo = SceneManager.Instance:DeleteMonsterVo(instance_id) if vo == nil then vo = SceneManager.Instance:DeletePartnerVo(instance_id) if vo == nil then vo = SceneManager.Instance:DeleteOtherVo(instance_id) if vo == nil then vo = SceneManager.Instance:DeleteRoleVo(instance_id) end end end end --服务器通知怪物出现 function SceneController:handler12007() local self = SceneController.Instance local monster_vo = SceneManager.Instance:CreateMonsterVo() monster_vo:ReadFromProtocal() local need_delay = true if monster_vo.hide_flag == 1 then need_delay = false end SceneManager.Instance:AddMonsterVo(monster_vo, need_delay) end --服务器通知场景对象移动 function SceneController:handler12008() local self = SceneController.Instance local pos_x, pos_y, instance_id = self:ReadFmt("hhi") local vo = SceneManager.Instance:GetSceneObjVo(instance_id) if vo then if self.scene:IsSceneLoaded() then if vo.vo_type == SceneBaseType.Monster then self.scene:MonsterMove(instance_id, pos_x, pos_y) if RoleManager.Instance:GetMainRoleVo():GetFlagsByKey(RoleVo.Act_Flag.CONVOY) > 0 and EscortModel:getInstance():IsFollowEscortCar() and EscortModel:getInstance():IsMyEscortCar(instance_id) then local temp_x,temp_y = EscortModel:GetInstance():GetTempPos() EscortModel:GetInstance():SetTempPos(pos_x,pos_y) if temp_x and temp_y then Scene.Instance.main_role:DoMove(Vector2(temp_x,temp_y)) end end elseif vo.vo_type == SceneBaseType.Partner then self.scene:PartnerMove(instance_id, pos_x, pos_y) elseif vo.vo_type == SceneBaseType.Other then self.scene:OtherMove(instance_id, pos_x, pos_y) elseif vo.vo_type == SceneBaseType.Role then self.scene:RoleMove(instance_id, pos_x, pos_y) end end else local delay_mon_vo = SceneManager.Instance:GetDelayMonsterVo(instance_id) if delay_mon_vo then delay_mon_vo.pos_x = pos_x delay_mon_vo.pos_y = pos_y end end end --角色血量变化 function SceneController:handler12009( ) local self = SceneController.Instance local obj_id, hp, maxHp = self:ReadFmt("lll") local objVo = SceneManager.Instance:GetSceneObjVo(obj_id) if objVo then GlobalEventSystem:Fire(EventName.EXECUTE_DELEY_FIGHT_INFO) local delta = hp - objVo.hp objVo:ChangeVar("maxHp", maxHp, nil, true) objVo:ChangeVar("hp", hp, nil, true) local obj = self.scene:GetSceneObj(obj_id) if obj then GlobalEventSystem:Fire(EventName.HP_CHANGE_FROM_SCENE, obj,delta ) if hp == 0 then local obj = self.scene:GetSceneObj(obj_id) obj:DoDead() end end else print("warning! can not find a obj to handle move response!") --没找到对象,先记录血量,等怪创建之后再赋值 local change_data = { hp = hp, maxHp = maxHp, } SceneManager.Instance:RecordPreMonsterData(obj_id,change_data) end end --场景角色属性更改 function SceneController:handler12010() local self = SceneController.Instance local role_id, len = self:ReadFmt("lh") local list = {} for i = 1, len do local obj = {} obj.style = self:ReadFmt("c") obj.value = self:ReadFmt("s") table.insert(list, obj) end Scene.Instance:RoleOtherProChange(role_id, list) end --服务器通知九宫格加载销毁角色对象 function SceneController:handler12011() local self = SceneController.Instance local add_num = self:ReadFmt("h") for i = 1,add_num do self:handler12003() end local remove_num = self:ReadFmt("h") for i = 1,remove_num do local role_id = self:ReadFmt("l") SceneManager.Instance:DeleteRoleVo(role_id) end end --服务器通知九宫格加载销毁非角色场景对象 function SceneController:handler12012() local self = SceneController.Instance local add_num = self:ReadFmt("h") for i = 1, add_num do self:handler12007() end add_num = self:ReadFmt("h") for i = 1, add_num do self:handler12014() end add_num = self:ReadFmt("h") for i = 1, add_num do self:handler12015() end local remove_num = self:ReadFmt("h") for i = 1, remove_num do self:handler12006() end --触发判断屏幕场景对象数量限制显示 GlobalEventSystem:Fire(SceneEventType.UPDATE_ROLE_LIMIT) end --广播玩家进入飘窗提示 function SceneController:handler12013() local self = SceneController.Instance --预生成table字段 local role_vo = { role_id = 0, name = "", sex = 1, career = 1, turn = 0, vip_type = 0, vip_flag = 0, level = 0, fighting = 0, picture = "", picture_ver = 0, profile_photo_id = 0, dress_id = 0, sup_vip_type = 0, } PictureProtoVo.ReadFmt(role_vo) local scene_info = SceneManager.Instance:GetSceneInfo(SceneManager.Instance:GetSceneId()) --获取场景信息 local scene_name = scene_info and scene_info.name or "场景" local data = { role_vo_1 = role_vo, --我方 role_vo_2 = nil, --敌方 type = 1, --UI类型 is_break = 1, --击杀情况(类型2需要使用) desc = string.format("进入了%s", scene_name), --描述 } if SceneManager:getInstance():IsWastelandPrepareScene() then -- 废土准备场景描述要改一下 data.desc = "进入了备战区" end if SceneManager:getInstance():IsShowDynamicInfoScene() then GlobalEventSystem:Fire(EventName.SHOW_DYNAMIC_INFO_TIP, data) end --造一个假的入场传闻 if SceneManager.Instance:IsBeachScene() then local data = { module_id = 418, id = 7, content = role_vo.name .. "," .. role_vo.role_id } GlobalEventSystem:Fire(EventName.RECEIVE_NEW_CHUANWEN, data, 11015)--传闻 end end --服务器通知普通场景对象进入 function SceneController:handler12014() local other_vo = OtherVo.New() other_vo:ReadFromProtocal() SceneManager.Instance:AddOtherVo(other_vo) end --服务器通知假人进入 function SceneController:handler12015() local role_vo = RoleVo.New() role_vo:ReadFakeProtacal() --校正假人坐标,避免创建出来掉到沟里 local main_role = Scene.Instance.main_role if main_role and main_role.vo then local main_height = Scene.Instance:GetZoneHeight(main_role.vo.pos_x/SceneObj.LogicRealRatio.x, main_role.vo.pos_y/SceneObj.LogicRealRatio.y) local temp_height = Scene.Instance:GetZoneHeight(role_vo.pos_x/SceneObj.LogicRealRatio.x, role_vo.pos_y/SceneObj.LogicRealRatio.y) if temp_height - main_height > 10 or temp_height - main_height < -10 then role_vo.pos_x = main_role.vo.pos_x role_vo.pos_y = main_role.vo.pos_y end end SceneManager.Instance:AddDelayRoleTable(role_vo) --延迟加载 if SceneManager.Instance:IsGodDungeon() then--如果是唤神副本,假人加载必须立刻刷新,不能使用栈模式先来后出的延迟加载,不然会导致旧数据覆盖新数据 SceneManager.Instance:ImmeAddRoleVo(role_vo.role_id) end end --通用状态变更通知 function SceneController:handler12016( ) local module_id, module_sub_id, role_id, value = self:ReadFmt("iils") print("HWR:SceneController [686]: ",module_id, module_sub_id, role_id, value) if module_id == 146 then if module_sub_id == 14609 then role_id = role_id or RoleManager.Instance.mainRoleInfo.role_id local role_vo = SceneManager.Instance:GetRoleVo(role_id) if not role_vo then return end role_vo:ChangeVar("is_ride",tonumber(value)) elseif module_sub_id >= 2000 + FosterConst.ModuleId.FJarvis and module_sub_id <= 2000 + FosterConst.ModuleId.FArmour then role_id = role_id or RoleManager.Instance.mainRoleInfo.role_id local role_vo = SceneManager.Instance:GetRoleVo(role_id) if not role_vo then return end local type_id = tonumber(module_sub_id) - 2000 local skin_id = stringtotable(value)[1] local star = stringtotable(value)[2] or 0 -- if type_id == FosterConst.ModuleId.FJarvis then -- role_vo:ChangeVar("pet_id",skin_id) -- elseif type_id == FosterConst.ModuleId.FGun then -- role_vo:ChangeVar("pet_weapon_id",skin_id) -- elseif type_id == FosterConst.ModuleId.FCloud then -- role_vo:ChangeVar("pet_wing_id",skin_id) -- elseif type_id == FosterConst.ModuleId.FArmour then -- role_vo:ChangeVar("pet_farmour",skin_id) -- end --调整皮肤的列表数据 if FosterController.Instance then local temp_data = {type_id = type_id, skin_id = skin_id, star = star} FosterController.Instance:ChangeRoleForsterSunSkinInfo(temp_data,role_id) end elseif FosterController.Instance then local temp_data = {type = module_sub_id,display = module_sub_id > 1000 and stringtotable(value) or tonumber(value)} FosterController.Instance:ChangeRoleForsterInfo(temp_data,role_id, module_sub_id < 1000) end elseif module_id == 147 then if module_sub_id == 1 then role_id = role_id or RoleManager.Instance.mainRoleInfo.role_id local role_vo = SceneManager.Instance:GetRoleVo(role_id) if not role_vo then return end role_vo:ChangeVar("light_id",tonumber(value)) end -- elseif module_id == 139 then -- 圣物系统 -- if module_sub_id == 0 then -- 圣物头衔等级 -- role_id = role_id or RoleManager.Instance.mainRoleInfo.role_id -- local role_vo = SceneManager.Instance:GetRoleVo(role_id) -- if not role_vo then return end -- role_vo:ChangeVar("ps_lv", tonumber(value)) -- end elseif module_id == 603 then -- 跨服主功能 if module_sub_id == 0 then -- 军衔等级 role_id = role_id or RoleManager.Instance.mainRoleInfo.role_id local role_vo = SceneManager.Instance:GetRoleVo(role_id) if not role_vo then return end role_vo:ChangeVar("military_ranks", tonumber(value)) end elseif module_id == 460 and module_sub_id == 1 then -- 赏金幻魔 role_id = role_id or RoleManager.Instance.mainRoleInfo.role_id local role_vo = SceneManager.Instance:GetRoleVo(role_id) if not role_vo then return end role_vo:ChangeVar("money_boss_protect_time", tonumber(value)) elseif module_id == 461 and module_sub_id == 1 then role_id = role_id or RoleManager.Instance.mainRoleInfo.role_id local role_vo = SceneManager.Instance:GetRoleVo(role_id) if not role_vo then return end role_vo:ChangeVar("deserted_boss_protect_time", tonumber(value)) end end --隐身字段广播 function SceneController:handler12070() local target_type, id, is_hide = self:ReadFmt("clc") local vo = nil if target_type == SceneBaseType.Monster then vo = SceneManager.Instance:GetMonsterVo(id) elseif target_type == SceneBaseType.Role or target_type == SceneBaseType.Fake_Role then vo = SceneManager.Instance:GetRoleVo(id) elseif target_type == SceneBaseType.Partner then vo = SceneManager.Instance:GetPartnerVo(id) end if vo then vo:ChangeVar("hide_flag", is_hide) end end --幽灵字段广播 function SceneController:handler12071() local target_type, id, is_ghost = self:ReadFmt("clc") local vo = nil if target_type == SceneBaseType.Monster then vo = SceneManager.Instance:GetMonsterVo(id) elseif target_type == SceneBaseType.Role or target_type == SceneBaseType.Fake_Role then vo = SceneManager.Instance:GetRoleVo(id) elseif target_type == SceneBaseType.Partner then vo = SceneManager.Instance:GetPartnerVo(id) end if vo then vo:ChangeVar("ghost_mode", is_ghost) end end --分组字段广播 function SceneController:handler12072() local target_type, id, warGroup = self:ReadFmt("cll") local vo = nil if target_type == SceneBaseType.Monster then vo = SceneManager.Instance:GetMonsterVo(id) elseif target_type == SceneBaseType.Role or target_type == SceneBaseType.Fake_Role then vo = SceneManager.Instance:GetRoleVo(id) elseif target_type == SceneBaseType.Partner then vo = SceneManager.Instance:GetPartnerVo(id) end if vo then vo:ChangeVar("warGroup", warGroup) end end --嘲讽buff追踪对象 function SceneController:handler12073() local target_type, target_id = self:ReadFmt("cl") SceneManager.Instance.chaofeng_attacker_compress_id = Scene.CompressObjId(target_type, target_id) end --展示状态广播 function SceneController:handler12075() local target_type, id, state_type = self:ReadFmt("clc") -- print("Saber:SceneController [660] target_type, id, state_type: ",target_type, id, state_type) local vo = nil if target_type == SceneBaseType.Monster then vo = SceneManager.Instance:GetMonsterVo(id) elseif target_type == SceneBaseType.Role or target_type == SceneBaseType.Fake_Role then vo = SceneManager.Instance:GetRoleVo(id) elseif target_type == SceneBaseType.Partner then vo = SceneManager.Instance:GetPartnerVo(id) end if vo then -- vo:ChangeVar("state_type", state_type) vo:ChangeVar("dance_status", state_type) if id == RoleManager.Instance:GetMainRoleId() then GlobalEventSystem:Fire(EventName.MAIN_ROLE_DANCE_STATUS_CHANGE,tonumber(state_type)) end end end --配对对象广播 function SceneController:handler12076() local role_id,date_role_id = self:ReadFmt("ll") local vo = SceneManager.Instance:GetRoleVo(role_id) if vo then vo:ChangeVar("date_role_id", date_role_id) else print("====can't find vo,role_id:",role_id) end end --玩家figure字段更新 function SceneController:handler12078() local role_id = self:ReadFmt("l") local role_vo = SceneManager.Instance:GetRoleVo(role_id) local role = Scene.Instance:GetRole(role_id) if role and role_vo then FigureProtoVo.ReadFmt(role_vo) if role_id == RoleManager.Instance:GetMainRoleId() then role_vo:ChangeFromVo(role_vo) GlobalEventSystem:Fire(EventName.MAINROLEHEAD_DATA_CHANGE, role_id) else role:InitRoleVo(role_vo) role:LoadInfoFromVo() end end end --场景对象非常用属性更改 function SceneController:handler12080() local instance_id = self:ReadFmt("i") local vo, obj_type = SceneManager.Instance:GetSceneObjVo(instance_id) if vo then local len = self:ReadFmt("h") local type, value for i = 1, len do type, value = self:ReadFmt("cl") if type == 1 then vo.pick_time = value elseif type == 2 then vo.owner_team_id = value elseif type == 3 then vo:ChangeVar("can_attack", value, nil, true) elseif type == 4 then vo:ChangeVar("can_pick", value, nil, true) elseif type == 5 then --怪物回血要做表现 local add_hp = value - vo.hp if add_hp > 0 then if obj_type and obj_type == SceneBaseType.Monster then local target = Scene.Instance:GetMonster(vo.instance_id) if target then FightDamageDisplayer:getInstance():ShowAddHp(add_hp, target) end end end vo:ChangeVar("hp", value, nil, true) elseif type == 6 then --PK保护结束时间搓 vo:ChangeVar("protect_time", value, nil, true) elseif type == 7 then vo:ChangeVar("level", value, nil, true) end end else --没找到对象,先把改变的等级记录一下 local len = self:ReadFmt("h") local type, value for i = 1, len do type, value = self:ReadFmt("cl") if type == 7 then local change_data = { level = value, } SceneManager.Instance:RecordPreMonsterData(instance_id,change_data) end end end end --场景对象血量变化 function SceneController:handler12081() local id, hp = self:ReadFmt("il") local target = Scene.Instance:GetSceneObj(id) if target ~= nil then local old_hp = target.vo.hp target.vo:ChangeVar("hp", hp, true) if hp == 0 then target:ForceDoDead() end local delta = hp - old_hp if delta > 0 then GlobalEventSystem:Fire(EventName.HP_CHANGE_FROM_SCENE, target, delta) end end end -- 人物速度改变 function SceneController:handler12082( ) local target_type, id, speed = self:ReadFmt("clh") if target_type == SceneBaseType.Monster then local vo = SceneManager.Instance:GetMonsterVo(id) if vo then vo:ChangeVar("move_speed",speed) end elseif target_type == SceneBaseType.Role or target_type == SceneBaseType.Fake_Role then local vo = SceneManager.Instance:GetRoleVo(id) if vo then vo:ChangeVar("move_speed",speed) end elseif target_type == SceneBaseType.Partner then local vo = SceneManager.Instance:GetPartnerVo(id) if vo then vo:ChangeVar("move_speed",speed) end end end --复活切换场景 function SceneController:handler12083( ) local rType, rsid, rx, ry, rsname, rhp, ryb, ybyb, yptime = self:ReadFmt("cihhsliih") if rType ~= 0 then RoleManager.Instance.mainRoleInfo:ChangeVar("pos_x",rx) RoleManager.Instance.mainRoleInfo:ChangeVar("pos_y",ry) end RoleManager.Instance.mainRoleInfo:ChangeVar("hp",rhp) RoleManager.Instance.mainRoleInfo:ChangeVar("jin",ryb) RoleManager.Instance.mainRoleInfo:ChangeVar("jinLock",ybyb) print("handler12083 rType, rx, ry, rsid, osid = " ,rType, rx, ry, rsid, SceneManager.Instance:GetSceneId()) local main_role = self.scene:GetMainRole() if rType == 0 then --切场景会发12083,位置是新场景的坐标 elseif rType == 1 then if main_role then main_role:SetRealPos(rx,ry) local function revive_callback() main_role:Revived() end main_role:DoRevive(revive_callback) end elseif rType == 2 then self:ReIntoScene(rsid, rsname, rx, ry) end if main_role then main_role:DeilyClearTrailRenderer() main_role:SetGhostMode(false) end GlobalEventSystem:Fire(EventName.RELIVE_COMPLETE) GlobalEventSystem:Fire(EventName.CLOSERELIVEWINDOW) GlobalEventSystem:Fire(EventName.REQUEST_RELIVE_TIMES) end --攻速改变 function SceneController:handler12084() local target_type, id, speed = self:ReadFmt("clh") if target_type == SceneBaseType.Monster then local vo = SceneManager.Instance:GetMonsterVo(id) if vo then vo:ChangeVar("att_speed",speed) end elseif target_type == SceneBaseType.Role or target_type == SceneBaseType.Fake_Role then local vo = SceneManager.Instance:GetRoleVo(id) if vo then vo:ChangeVar("att_speed",speed) end elseif target_type == SceneBaseType.Partner then local vo = SceneManager.Instance:GetPartnerVo(id) if vo then vo:ChangeVar("att_speed",speed) end end end --玩家区域改变 function SceneController:handler12085() local role_id, safe_area_state = self:ReadFmt("lc") local role_vo = SceneManager.Instance:GetRoleVo(role_id) if role_vo then role_vo:ChangeVar("safe_area_state", safe_area_state, nil, true) end end --玩家名字改变 function SceneController:handler12086() local role_id, role_name = self:ReadFmt("ls") local role_vo = SceneManager.Instance:GetRoleVo(role_id) if role_vo then role_vo:ChangeVar("name", role_name) end end --重新进入场景 function SceneController:ReIntoScene( rsid, rsname, pos_x, pos_y ) local old_scene = SceneManager.Instance:GetSceneId() SceneManager.Instance:SetCurrentSceneId(rsid) SceneManager.Instance:ClearAllVo() if rsid ~= old_scene then GlobalEventSystem:Fire(SceneEventType.OPEN_SCENE_LOAD_VIEW) self.scene:ClearScene() SceneManager.Instance:SceneStart() self.scene:SceneLoadingEnter(rsid) self.scene:CreateMainRole() GlobalEventSystem:Fire(SceneEventType.SCENE_CHANGED, rsid) else if self.scene:GetMainRole() then --要调用一次这个,让主角位置移过去,并且设置高度 self.scene:GetMainRole():SetGhostMode(false) self.scene:GetMainRole():SetRealPos(pos_x,pos_y) self.scene:GetMainRole():Revived() local function revive_callback( ) self.scene:GetMainRole():Revived() self.scene:GetMainRole():LoadInfoFromVo() end self.scene:GetMainRole():DoRevive(revive_callback) end self:LoadSceneInfoRequest(rsid) end end --[[ 动态NPC列表 ## 查询场景的显示NPC 协议号:12100 c >> s: int:32 场景ID s >> c: array( int32 NPCID int:32 场景ID x:32 X坐标 y:32 Y坐标 ) ]] function SceneController:handler12100( ... ) local scmd = SCMD12100.New(true) local list = {} for k,v in pairs(scmd.npc_list) do list[v.npc_id] = v end SceneManager.Instance:SetNpcList(list) --申请12002切换场景 -- local send_times = 0 -- local function timeout_func() -- send_times = send_times + 1 -- if send_times <= 4 and not LoginModel.Instance.is_back_from_game then self:SendFmtToGame(12002, "") -- self:AddSendFmtCheckout(12002, 3, timeout_func) -- end -- end -- timeout_func() end --[[ NPC状态变更 ## 场景中动态改变NPC状态 协议号:12103 c >> s: 无 s >> c: int32 NPCID int8 0不显示 1显示 int:32 场景ID x:32 X坐标 y:32 Y坐标 ]] function SceneController:handler12103( ... ) local scmd = SCMD12103.New(true) if scmd.npc_list then for i,v in ipairs(scmd.npc_list) do if v.scene_id == SceneManager.getInstance():GetSceneId() then if v.is_show == 0 then SceneManager.Instance:DynamicDelNpc(v.npc_id) else SceneManager.Instance:DynamicAddNpc(v.npc_id, v.x, v.y, v.args) end end end end end --[[ 功能: Npc显示图标更新反馈 协议号: 12020 来源: s 参数: 其它: 作者: deadline ]] function SceneController:handler12020( ) local npc_num = self:ReadFmt("h") for i=1,npc_num do local npc_ins_id, task_flag = self:ReadFmt("ic") local npcvo = SceneManager.Instance:GetNpcVo(npc_ins_id) if npcvo then npcvo:ChangeVar("task_icon",tonumber(task_flag)) end end end --怪物说话ai function SceneController:handler12023( ) local monster_id = self:ReadFmt("i") local content = self:ReadFmt("s") local monster = Scene.Instance:GetMonster(monster_id) if monster then monster:CreateTalkBoard(1, content, 200, 5) end end -- 玩家动作播放 function SceneController:handler12025( ) local result, action = self:ReadFmt("ic") -- print("Saber:SceneController [1125] result, action: ",result, action) if result == 1 then -- 动作 0取消 1社团祝火 GuildModel:getInstance()._waiting_12025_respon = false -- 是否等待12025玩家状态协议返回状态 GlobalEventSystem:Fire(EventName.MAIN_ROLE_DANCE_STATUS_CHANGE,action) RoleManager.Instance.mainRoleInfo:ChangeVar("dance_status", action) else ErrorCodeShow(result) end end -- 对象死亡(一般是服务端能杀死无限血怪物,要走单独的清除逻辑) function SceneController:handler12027( ) local self = SceneController.Instance --竞技场不通过服务器清除场景对象 local instance_id = self:ReadFmt("i") local monster = self.scene:GetMonster(instance_id) if monster then -- 播放死亡动作 monster:DoDead() local function delay_method( ) self.scene_mgr:DeleteMonsterVo(instance_id) end -- 延迟销毁 setTimeout(delay_method, 5) end end --注册场景事件 function SceneController:RegisterAllEvents() local gameStartHandler = function () SceneController.Instance.is_game_started = true if LoginModel.Instance.reconnect_on_game == nil or LoginModel.Instance.reconnect_on_game == false then --SceneManager:getInstance():GameStartClearCache() else Message.show("重连成功") if LoginModel.Instance then LoginModel.Instance.reconnect_on_game = false end GlobalEventSystem:Fire(EventName.HIDE_LOADING_VIEW) end SceneManager:getInstance():GameStartClearCache() -- 登录时候由服务端主推,不要主动请求了,服务端说会覆盖坐标-20210112 -- local vo = RoleManager.Instance.mainRoleInfo -- self:SendFmtToGame(12005, "iicchh", vo.dun_id, vo.lastSceneId, 0, 0, 0, 0) if ClientConfig.is_simulator then InitSimulatorSetting() end end local function onSceneStart() -- 切换场景寻路 Scene.Instance:FindContinue() self:SendFmtToGame("12020") end --场景寻路 local path_find = function(findVo) --寻路要先切换掉自动挂机状态 GlobalEventSystem:Fire(EventName.STOPAUTOFIGHT, false, true) Scene.Instance:FindElement(findVo) end local function onRequestChangeScene(scene_id, call_back_type, send_type, pos_x, pos_y,force_show_action) local data = { scene_id = scene_id, call_back_type = call_back_type, send_type = send_type, x = pos_x, y = pos_y, force_show_action = force_show_action, } self:ClientRequestChangeScene(12005, data) end local moveRequestHandler = function(x, y, flag, args_1, args_2,args_3, args_4) if not self.scene or not self.scene:GetMainRole() then return end local rx,ry = self.scene:GetMainRole():GetRealPos() x = x < 0 and 0 or math.floor(x) y = y < 0 and 0 or math.floor(y) rx = rx < 0 and 0 or math.floor(rx) ry = ry < 0 and 0 or math.floor(ry) args_1 = args_1 or 0 args_2 = args_2 or 0 args_3 = args_3 or 0 args_4 = args_4 or 0 if flag then flag = flag < 0 and 0 or math.floor(flag) else flag = 0 end --以前的做法是把当前的real_pos当做目标坐标,现在改为非走路类型都靠传参决定 if flag ~= 0 then rx, ry = x, y end local scene_id = SceneManager.Instance:GetSceneId() if scene_id then scene_id = scene_id < 0 and 0 or math.floor(scene_id) else scene_id = 0 end -- if flag == 4 then -- print(">>>>>>>> 12001 >>>> ", flag, args_1, args_2, args_3, args_4) -- end -- if flag == 0 then -- print("tanar: [SceneController 1101]=> rx, ry: ",rx, ry) -- end --相同位置不发送协议 self.last_send_pos = self.last_send_pos or {} if self.last_send_pos.scene_id == scene_id and self.last_send_pos.rx == rx and self.last_send_pos.ry == ry and self.last_send_pos.flag == flag then return end self.last_send_pos = { scene_id = scene_id, rx = rx, ry = ry, flag = flag} self:SendFmtToGame(12001, "ihhchhhh", scene_id, rx, ry, flag, args_1, args_2, args_3, args_4) end local function onSafeAreaChange(state) self:SendFmtToGame(12085, "c", state) end local function onOutOfStuck() self:OutOfStuck() end local function onFlyShoe( scene_id, x, y ) local main_role = Scene.Instance:GetMainRole() -- if main_role:IsInState(PoseState.JUMP) then -- Message.show("跳跃中无法使用小飞鞋") -- else GlobalEventSystem:Fire(EventName.STOPAUTOFIGHT,false,true) GlobalEventSystem:Fire(EventName.STOP_AUTO_DO_TASK) -- 移动距离近,正常寻路 local cur_scene_id = SceneManager.Instance:GetSceneId() if scene_id == cur_scene_id then local pos = co.Vector2(x,y) local main_role = Scene.Instance:GetMainRole() local distance = GameMath.GetDistance(pos.x, pos.y, main_role.real_pos.x, main_role.real_pos.y, true) print('Ych:SceneController.lua[1326] distance', distance) local start_height = Scene.Instance:GetZoneHeight(main_role.real_pos.x / SceneObj.LogicRealRatio.x,main_role.real_pos.y / SceneObj.LogicRealRatio.y) --起跳点的高度 local end_height = Scene.Instance:GetZoneHeight(pos.x / SceneObj.LogicRealRatio.x, pos.y / SceneObj.LogicRealRatio.y) if distance > FLY_SHOE_DISTANCE.ThreeJumpDistance or (end_height - start_height) > 5 or (start_height - end_height ) > 5 then --飞天落地需要消耗小飞鞋 else local fly_data = AutoFightController.getInstance():GetFlyData() if distance < FLY_SHOE_DISTANCE.NormalMoveDistance then local findVo = FindVo.New() findVo.type = FindVo.POINT findVo.sceneId = scene_id findVo.x = x / SceneObj.LogicRealRatio.x findVo.y = y / SceneObj.LogicRealRatio.y findVo.call_back = fly_data and fly_data.callback GlobalEventSystem:Fire(EventName.FIND, findVo) --如果数走路过去,才不需要消耗小飞鞋 return else --多段跳需要消耗小飞鞋 end end end self:SendFmtToGame(12033, "i", scene_id) -- end end GlobalEventSystem:Bind(SceneManager.START,onSceneStart) GlobalEventSystem:Bind(EventName.GAME_START, gameStartHandler) GlobalEventSystem:Bind(SceneEventType.REQUEST_CHANGE_SCENE, onRequestChangeScene) GlobalEventSystem:Bind(EventName.FIND, path_find) GlobalEventSystem:Bind(SceneEventType.MOVEREQUEST, moveRequestHandler) GlobalEventSystem:Bind(SceneEventType.SAFE_AREA_CHANGE, onSafeAreaChange) GlobalEventSystem:Bind(SceneEventType.OUT_OF_STUCK, onOutOfStuck) GlobalEventSystem:Bind(SceneEventType.REQUEST_USE_FLY_SHOE, onFlyShoe) local function onRequestSceneInfo() self:LoadSceneInfoRequest() end GlobalEventSystem:Bind(SceneEventType.REQUEST_SCENE_INFO, onRequestSceneInfo) local function request_dynamic() self:SendFmtToGame(12030) end GlobalEventSystem:Bind(SceneEventType.REQUEST_DYNAMIC_ARER, request_dynamic) local function request_effect() self:SendFmtToGame(12032) end GlobalEventSystem:Bind(SceneEventType.REQUEST_DYNAMIC_EFFECT, request_effect) local function request_pos(scene_id, line, x, y) local data = { scene_id = scene_id, line = line, x = x, y = y, } self:ClientRequestChangeScene(12034, data) end GlobalEventSystem:Bind(SceneEventType.REQUEST_POS_LINK, request_pos) local function scene_load_completed() if not Scene.Instance:IsNpcLoadFinish() then return end --通知服务器完成了场景切换 self:SendFmtToGame(12035) GlobalEventSystem:Fire(SceneEventType.REQUEST_DYNAMIC_EFFECT) end GlobalEventSystem:Bind(EventName.NOTICE_SCENE_LOAD_WILL_COMPLETE, scene_load_completed) local function deal_with_drop_list_vo(vo,is_fake) self:DealWithDropListVo(vo,is_fake) end GlobalEventSystem:Bind(SceneEventType.DEAL_WITH_SCENE_DROP_LIST_VO, deal_with_drop_list_vo) end --超链接场景传送 function SceneController:handler12034( ) local error_code,x,y = self:ReadFmt("ihh") if error_code ~= 1 then ErrorCodeShow(error_code) else --寻路 local findVo = FindVo.New() findVo.sceneId = SceneManager:getInstance():GetSceneId() findVo.type = FindVo.POINT findVo.x = x/SceneObj.LogicRealRatio.x findVo.y = y/SceneObj.LogicRealRatio.y GlobalEventSystem:Fire(EventName.FIND,findVo) end end --怪物掉落 function SceneController:handler12017( ) local vo = {} local len2 vo.mon_id, vo.expire_time_stamp, vo.map_id, len2 = self:ReadFmt("iiih") vo.drop_list = vo.drop_list or {} local vo2 = nil for i = 1,len2 do vo2 = { drop_id = self:ReadFmt("i"), drop_type = self:ReadFmt("c"), type_id = self:ReadFmt("i"), drop_num = self:ReadFmt("i"), role_id = self:ReadFmt("l"), pos_x = self:ReadFmt("h"), pos_y = self:ReadFmt("h"), effect = self:ReadFmt("s"), drop_icon = self:ReadFmt("s"), expire_time_stamp = vo.expire_time_stamp, map_id = vo.map_id, } table.insert(vo.drop_list,vo2) end vo.pos_x = self:ReadFmt("h") vo.pos_y = self:ReadFmt("h") vo.boss_type = self:ReadFmt("c") if len2 > 0 then GlobalEventSystem:Fire(SceneEventType.DEAL_WITH_SCENE_DROP_LIST_VO, vo) end end --掉落消失 function SceneController:handler12019( ) local drop_id = self:ReadFmt("i") or 0 GlobalEventSystem:Fire(SceneEventType.DISMiSS_SCENE_DROP_ITEM, drop_id) end --玩家上线后能看到身边周围的怪物掉落 function SceneController:handler12018( ) local vo = {} vo.drop_list = {} local tb = nil local map_id = SceneManager:getInstance():GetSceneId() local len = self:ReadFmt("h") for i = 1,len do tb = { drop_id = self:ReadFmt("i"), drop_type = self:ReadFmt("c"), type_id = self:ReadFmt("i"), drop_num = self:ReadFmt("i"), role_id = self:ReadFmt("l"), pos_x = self:ReadFmt("h"), pos_y = self:ReadFmt("h"), effect = self:ReadFmt("s"), drop_icon = self:ReadFmt("s"), expire_time_stamp = self:ReadFmt("i"), map_id = map_id, } tb.no_anim = true table.insert(vo.drop_list,tb) end vo.map_id = SceneManager:getInstance():GetSceneId() if len > 0 then GlobalEventSystem:Fire(SceneEventType.DEAL_WITH_SCENE_DROP_LIST_VO, vo) end end --攻防两方都飘字的角色血量变化 function SceneController:handler12024( ) local attacker_id, obj_id, hp, maxHp = self:ReadFmt("llll") local objVo = SceneManager.Instance:GetSceneObjVo(obj_id) if objVo then GlobalEventSystem:Fire(EventName.EXECUTE_DELEY_FIGHT_INFO) local delta = hp - objVo.hp local obj = self.scene:GetSceneObj(obj_id) local attacker = self.scene:GetSceneObj(attacker_id) if obj and attacker then GlobalEventSystem:Fire(EventName.HP_CHANGE_FROM_SCENE, obj,delta,attacker) end objVo:ChangeVar("hp", hp) objVo:ChangeVar("maxHp", maxHp) if hp == 0 then local obj = self.scene:GetSceneObj(obj_id) obj:DoDead() end else print("warning! can not find a obj to handle move response!") end end --改变动态区域属性 function SceneController:handler12030( ) local len = self:ReadFmt("h") or 0 for i=1,len do local area_id, area_type = self:ReadFmt("cc") if area_id and area_type then local client_index = ServerAreaIndex[area_type] if client_index then Scene.Instance:SetDynamicArea(area_id,client_index) end end end end --改变场景内特效 function SceneController:handler12032( ) local scene_id = self:ReadFmt("i") if not scene_id or SceneManager:getInstance():GetSceneId() ~= scene_id then return end local function onChangeState(vo) if vo.type == 0 then SapManager:getInstance():UnRegisterObj(SapManager.ObjType.Effect, vo.eff_id) elseif vo.type == 1 then local mapView = MapView.Instance if mapView then local scene_effect = Config.ConfigSceneEffect.EffectInfo[tonumber(mapView.curMapId)] if not scene_effect then return end local effect = scene_effect[vo.eff_id] if not effect then return end effect.id = vo.eff_id local obj = { id = vo.eff_id, type = SapManager.ObjType.Effect, pos = co.TableXY(effect.x,effect.y), size = co.TableXY(effect.bound.size_x + effect.bound.off_x,effect.bound.size_y+ effect.bound.off_y), data = {id = vo.eff_id,obj = effect}, } SapManager:getInstance():RegisterObj(obj) end end end local len = self:ReadFmt("h") or 0 local vo = nil for i=1,len do vo = { eff_id = self:ReadFmt("h") or 0, type = self:ReadFmt("c") } onChangeState(vo) end end --使用小飞鞋结果返回 function SceneController:handler12033( ) local error_code = self:ReadFmt("i") if error_code ~= 1 then ErrorCodeShow(error_code) else GlobalEventSystem:Fire(SceneEventType.REQUEST_USE_FLY_SHOE_RETURN) end end --boss的归属标识 function SceneController:handler12022( ) local player_id, boss_flag = self:ReadFmt("lc") local list = Scene.Instance.role_list if list then for k,v in pairs(list) do if player_id==v:GetVo().role_id then v:GetVo():ChangeVar("boss_flag", boss_flag) break end end end end --改变玩家活动通用标识 function SceneController:handler12089() local self = SceneController.Instance local flag = {} flag.role_id = self:ReadFmt("l") local len = self:ReadFmt("h") flag.activity_flags = {} for i = 1, len do local obj = {} obj.key = self:ReadFmt("c") obj.value = self:ReadFmt("l") table.insert(flag.activity_flags, obj) end self.scene:FlagChange(flag.role_id, flag.activity_flags) end --改变玩家活动通用标识 function SceneController:handler12090() local instance_id = self:ReadFmt("l") local len = self:ReadFmt("h") local type, value,str local vo, obj_type = SceneManager.Instance:GetSceneObjVo(instance_id) if vo then for i = 1, len do type, value ,str = self:ReadFmt("cls") if type == 1 then vo.name = str vo:ChangeVar("name", str, nil, true) end end else for i = 1, len do type, value ,str = self:ReadFmt("cls") end --没找到对象,先记录数据,等创建出来再用 local change_data = { name = str, } SceneManager.Instance:RecordPreMonsterData(instance_id,change_data) print("warning! can not find a obj to handle move response!") end end --[[ %% 移动协议错误通知 %% 用于告知客户端错误原因 -define(MOTION_ERR_OK, 0). % 非错误[实际上不通知] -define(MOTION_ERR_SCENE, 1). % 错误目标场景 -define(MOTION_ERR_CD, 2). % CD时间 -define(MOTION_ERR_DIS, 3). % 距离超限 ]] function SceneController:handler12099( ) self.cache_move_error_type = self.cache_move_error_type or {} local target_scene, real_scene, target_pos_x, target_pos_y, move_type, real_pos_x, real_pos_y, code = self:ReadFmt("iihhchhc") if code and code >= 1 then if self.cache_move_error_type[code] then return end self.cache_move_error_type[code] = true local real_is_block = false if SceneManager:getInstance():IsBlockXY(real_pos_x/SceneObj.LogicRealRatio.x, real_pos_y/SceneObj.LogicRealRatio.y) then real_is_block = true end Message.show("移动操作失败") local error_str = string.format("移动操作失败: target_scene = %d, real_scene = %d, target_pos_x = %d, target_pos_y = %d, move_type = %d, real_pos_x = %d, real_pos_y = %d, code = %d, real_is_block = %s",target_scene, real_scene, target_pos_x, target_pos_y, move_type, real_pos_x, real_pos_y, code, tostring(real_is_block)) GameError.Instance:SendErrorToPHP(error_str) end end --场景掉落处理 --is_fake是否是副本的假掉落 function SceneController:DealWithDropListVo(vo,is_fake) --处理掉在障碍区的坐标 local logic_x local logic_y local pos for k,v in pairs(vo.drop_list) do logic_x = v.pos_x/SceneObj.LogicRealRatio.x logic_y = v.pos_y/SceneObj.LogicRealRatio.y if SceneManager:getInstance():IsBlockXY(logic_x, logic_y) then pos = SourceOperateMove.FindNoBlockPos(Vector2(logic_x, logic_y)) v.pos_x = pos.x*SceneObj.LogicRealRatio.x v.pos_y = pos.y*SceneObj.LogicRealRatio.y end end local copy_vo = { mon_id = vo.mon_id, -- expire_time_stamp = vo.expire_time_stamp, map_id = vo.map_id, pos_x = vo.pos_x, pos_y = vo.pos_y, boss_type = vo.boss_type, drop_list = {} } local len = #vo.drop_list local start_index = 1 local onUpdate = function ( ) if start_index <= len then local tb = DeepCopy(copy_vo) for i=start_index,start_index do if i <= len then table.insert(tb.drop_list, vo.drop_list[i]) end end start_index = start_index + 1 GlobalEventSystem:Fire(SceneEventType.BROADCAST_SCENE_DROP_LIST, tb) end end local function delay_fun( ... ) if len > 1 then --分批掉落 每次掉落1个物品 onUpdate() GlobalTimerQuest:AddPeriodQuest(onUpdate, 0.2, len) else GlobalEventSystem:Fire(SceneEventType.BROADCAST_SCENE_DROP_LIST, vo) end end local time = 0.15 if is_fake then if Status.NowTime - RoleManager.Instance.mainRoleInfo.last_level_time < 1 then time = 0.4 end end setTimeout(delay_fun,time) end --客户端请求切换场景总入口 function SceneController:ClientRequestChangeScene(type_id, data ) local call = function() if type_id == 12005 or type_id == -1 then self:requestChangeScene(data.scene_id, data.call_back_type, data.send_type, data.x, data.y) elseif type_id == 12034 then self:SendFmtToGame(12034, "ihhh", data.scene_id, data.line, data.x, data.y) elseif type_id == 12041 then self:SendFmtToGame(data.id, "h", data.args) elseif type_id == 61001 then self:SendFmtToGame(type_id,"i", data.scene_id) elseif type_id == 61002 then self:SendFmtToGame(type_id) elseif type_id == 17402 then --中午答题进入场景 self:SendFmtToGame(17402) end end if type_id == 61001 then local config = Config.Dungeoncfg[data.scene_id] if config then self.request_scene_id = config.scene_id end else self.request_scene_id = data.scene_id end Scene.Instance:PreLoadMapRes(self.request_scene_id) call() end function SceneController:LateUpdate(now_time, elapse_time) self.late_update_frame_index = self.late_update_frame_index or 0 self.late_update_frame_index = self.late_update_frame_index + 1 self.late_update_update_elapse_time = self.late_update_update_elapse_time or 0 self.late_update_update_elapse_time = self.late_update_update_elapse_time + elapse_time -- if G_DEBUG_UPDATE_STEP and self.late_update_frame_index % G_DEBUG_UPDATE_STEP ~= 0 then -- return -- end if self.late_update_frame_index % lua_viewM:GetFrameUpdateCount() ~= 0 then return end self.scene:LateUpdate(now_time, self.late_update_update_elapse_time) self.late_update_update_elapse_time = 0 --计算帧率 -- if self.scene_mgr.calculate_framerate_end_time and now_time - self.scene_mgr.calculate_framerate_end_time > 0 then -- local total_count = Time.frameCount - self.scene_mgr.calculate_framerate_start_count -- local frame_rate = total_count / self.scene_mgr.calculate_framerate_last_time + 2 -- self.scene_mgr.curr_frame_rate = frame_rate -- if self.is_first_set_frameRate then -- self.is_first_set_frameRate = false -- GlobalEventSystem:Fire(EventName.CALCULATE_FRAME_COMPLETE, frame_rate) -- end -- if frame_rate > 30 then -- self.scene_mgr.calculate_framerate_end_time = false -- self.scene_mgr:SetNextCkeckPerformanceTime(60) -- else -- self.scene_mgr.calculate_framerate_end_time = false -- end -- end end