源战役客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

1794 rivejä
58 KiB

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