require("game.scene.MapView") require("game.scene.SkyBox") require("game.scene.SapManager") require("game.scene.SceneConfig") require("game.scene.SceneDropObj") require("game.scene.SceneDropManager") require("game.scene.sceneBoard.NameBoard") require("game.scene.sceneBoard.NameBoardManager") require("game.scene.sceneBoard.TalkBoard") require("game.scene.sceneobj.MoveObj") require("game.scene.sceneobj.ObjPool") require("game.scene.sceneobj.SceneObj") require("game.scene.sceneobj.Door") require("game.scene.sceneobj.Character") require("game.scene.sceneobj.Monster") require("game.scene.sceneobj.Other") require("game.scene.sceneobj.Role") require("game.scene.sceneobj.Partner") require("game.scene.sceneobj.MainRole") require("game.scene.sceneobj.Npc") require("game.scene.sceneobj.Clothe") require("game.scene.sceneobj.Weapon") require("game.scene.sceneobj.PoseState") require("game.scene.sceneobj.FindVo") require("game.scene.sceneobj.JumpPoint") require("game.scene.sceneobj.WayPoint") require("game.scene.sceneobj.Sprite") require("game.scene.sceneobj.Pet") require("game.scene.sceneobj.Baby") require("game.scene.sceneobj.HeadWear") require("game.scene.sceneobj.Evil") require("game.scene.sceneobj.Grave") require("game.scene.sceneobj.ImageObj") require("game.scene.sceneobj.HookRole") require("game.scene.sceneobj.Pokemon") require("game.scene.sceneobj.AssisitPokemon") require("game.scene.sceneobj.Build") require("game.scene.sceneobj.Furniture") require("game.scene.sceneobj.BuildBaby") require("game.scene.sceneobj.GWFollower") require("game.scene.sceneobj.GalaxyPearl") require("game.scene.sceneobj.JumpOneStep") require("game.sharedata.PartnerVo") require("game.sharedata.MonsterVo") require("game.sharedata.MonsterTypeVo") require("game.sharedata.NpcVo") require("game.sharedata.DoorVo") require("game.sharedata.OtherVo") require("game.sharedata.JumpPointVo") require("game.sharedata.SpriteVo") require("game.sharedata.EvilVo") require("game.sharedata.PetVo") require("game.sharedata.BabyVo") require("game.sharedata.GraveVo") require("game.sharedata.HookRoleVo") require("game.sharedata.PokemonVo") require("game.sharedata.GWFollowerVo") require("game.sharedata.AssisitPokemonVo") Scene = Scene or BaseClass() local Scene = Scene local GameMath = GameMath local GlobalEventSystem = GlobalEventSystem local SceneEventType = SceneEventType local math = math local table_insert = table.insert local table_sort = table.sort local SapManager = SapManager local Config = Config local tonumber = tonumber local EventName = EventName local IsTableEmpty = IsTableEmpty local GameMath_GetDistance = GameMath.GetDistance local GameMath_IsPointNear = GameMath.IsPointNear local lua_viewM = lua_viewM local co_TableXY = co.TableXY local SceneObj_LogicRealRatio_x = SceneObj.LogicRealRatio.x local SceneObj_LogicRealRatio_y = SceneObj.LogicRealRatio.y local co_NormaliseXYTable = co.NormaliseXYTable --寻找目标类型 Scene.FIND_TARGET_TYPE = { monster = 1, role = 2, partner = 3, all = 100, } function Scene:__init() if Scene.Instance ~= nil then LogError("Scene is a singleton class") end Scene.Instance = self self.mapView = MapView:getInstance() self.main_camera = MainCamera:getInstance() self.main_role = nil self.SkillMgr = SkillManager:getInstance() self.scene_mgr = SceneManager:getInstance() self.role_mgr = RoleManager:getInstance() self.mainrole_vo = self.role_mgr.mainRoleInfo self.config_mgr = ConfigItemMgr.Instance self.nameBoard_mgr = NameBoardManager.getInstance() self.auto_fight_mgr = AutoFightManager:getInstance() -- self.fight_back_mgr = FightBackManager:getInstance() self.role_list = {} --玩家列表 包括主角 self.partner_list = {} --伙伴列表 self.monster_list = {} --怪物列表 self.other_list = {} --其他对象列表 self.npc_list = {} --Npc列表 self.door_list = {} --door列表 self.drop_list = {} --掉落列表 self.sprite_list = {} --小精灵列表 self.evil_list = {} --小精灵列表 self.pet_list = {} --ai娘列表 self.pokemon_list = {} --宠物列表 self.assisit_pokemon_list = {} --宠物副本协战宠物列表 self.baby_list = {} --宝宝列表 self.gwfollower_list = {} --本服团战粮草护送 self.jumppoint_list = {} --跳点列表 self.waypoint = nil --路径点 self.grave_list = {} --怪物墓碑列表 self.build_list = {} --家园建筑列表 self.furniture_list = {} --家园家具列表 self.hook_role_list = {} --离线挂机玩家列表 self.build_baby_list = {} --家园建筑列表 self.jump_one_step_list = {} --跳一跳跳台列表 self.monster_pool = ObjPool.New(ObjMaxCache.Monster) self.other_pool = ObjPool.New(ObjMaxCache.Other) self.evil_pool = ObjPool.New(ObjMaxCache.Evil) self.role_pool = ObjPool.New(ObjMaxCache.OtherRole) self.partner_pool = ObjPool.New(ObjMaxCache.Partner) self.npc_pool = ObjPool.New(ObjMaxCache.NPC) self.drop_pool = ObjPool.New(ObjMaxCache.DropItem) self.sprite_pool = ObjPool.New(ObjMaxCache.Sprite) self.pet_pool = ObjPool.New(ObjMaxCache.Pet) self.pokemon_pool = ObjPool.New(ObjMaxCache.Pokemon) self.assisit_pokemon_pool = ObjPool.New(ObjMaxCache.AssisitPokemon) self.baby_pool = ObjPool.New(ObjMaxCache.Baby) self.gwfollower_pool = ObjPool.New(ObjMaxCache.GWFollower) self.grave_pool = ObjPool.New(ObjMaxCache.Grave) self.hook_role_pool = ObjPool.New(ObjMaxCache.HookRole) self.jump_one_step_pool = ObjPool.New(ObjMaxCache.JumpOneStep) --延时处理的函数列表(用于处理延时删除等逻辑) self.delay_handle_funcs = {} --怪物尸体列表 self.dead_body_list = {} self.dead_body_count = 0 --预加载的资源是否加载完 self.preload_res_is_loaded = false --场景数据是否加载完 self.scene_data_loaded = false --场景是否正在执行update的方法 self.is_in_update = false --场景更新步频 self.update_scene_times_index = 0 --场景更新消耗时间 self.update_elapse_time = 0.0 --场景更新步频 self.late_update_scene_times_index = 0 --场景更新消耗时间 self.late_update_elapse_time = 0.0 --是否在一键拾取状态中 self.is_in_pick_all_state = false self:InitEvents() self:InitSAPFunction() self.last_dir_move_end_time = 0 --遥感上次操作时间 self.last_attack_time = 0 --上次自动攻击的时间 self.last_find_target_time = 0 --上次自动寻怪的时间 self.last_ranAttackObj = nil --上次技能攻击主要目标 self.last_auto_pick_id = false --上一个自动采集物的id self.last_auto_pick_time = false --上一个自动采集物成功采集的时间 self.auto_find_and_attack_interval = Config.otherFightInfo.mainrole_autoAttack_interval --最小寻怪和攻击间隔 self.god_open_level = Config.ConfigOpenLv.FunctionIconOpenLv.God --降神开放等级 --当前选中对象 self.curr_click_target = nil --点击屏幕的初始点 self.touch_bengin_y = 0 self.touch_bengin_x = 0 --是否允许点击屏幕 self.enable_click_screen = true self.update_role_name = false self.update_monster_name = false self.update_partner_name = false self.update_role_mode = false self.cur_jump_index = 0 self.jump_count = 0 --是否过场景状态 self.is_loading_scene = false self.user_manul_time = 0 --上次自动拾取物品时间 self.auto_pick_time = 0 --选中目标特效对象 self.click_target_effect = nil self.jump_curr_trigger_index = false self.check_visible_role_num_time = false self.curr_click_target = false self.manual_target = false --是否12002 回来 加载npc结束 self.load_npc_finish = false --是否加载进度条加载完成 self.load_progress_finished = false --挂机优先选择目标配置 self.target_auto_fight_cfg = false self.find_monster_pos = false --设置找怪物的点,在这个点附近开启寻怪自动打模型 self.request_change_god_time = 0 self.is_first_enter_game = true --启动游戏后第一次进场景 self.is_first_enter_scene = true --从创角选角流程后第一次进场景 self.is_first_load_bg_finish = false --第一次进场景背景图加载结束 self.load_scene_timeout_max = false --延长加载场景超时时间 self.can_opt_joy_stick = true --是否可以操作遥杆 self.pick_drop_distance = 1000 --掉落的拾取距离p self.only_main_role_pick = false --是否只使用主角拾取, self.need_change_move_speed = false --是否需要改变拾取速度 self.find_monster_distance = 1000 --寻路开启自动挂机的距离的平方 self.preload_max_time = 20 self.pre_check_distance = 1000 --预选目标的检测距离,手动情况下生效 self.is_in_babydun = false -- 是否允许自动挂机 self.is_showing_sky_box = false --当前是否在显示天空盒 end function Scene:getInstance() if Scene.Instance == nil then Scene.New() end return Scene.Instance end function Scene:AddLayerSceneListener() local layer_scene = UiFactory.GetSceneCanvas().gameObject local onScreenDown = function(targer,x,y) if self.enable_click_screen then self:OnTouchBegin(x,y) GlobalEventSystem:Fire(SceneEventType.SCENE_TOUCH_DOWN, {x = x, y = y}) if Input.GetMouseButtonDown(0) then self.mouse_down = true end end end local onScreenUp = function(targer,x,y) if self.enable_click_screen then self:OnTouchEnd(x,y) GlobalEventSystem:Fire(SceneEventType.SCENE_TOUCH_UP, {x = x, y = y}) self.mouse_down = false end end local function onScreenDrag(target,x, y) if self.enable_click_screen then self:OnDrag(x, y) GlobalEventSystem:Fire(SceneEventType.SCENE_TOUCH_MOVE, {x = x, y = y}) end end AddDragEvent(layer_scene,onScreenDrag) AddDownEvent(layer_scene,onScreenDown) AddUpEvent(layer_scene,onScreenUp) end function Scene:InitEvents() self:AddLayerSceneListener() local function roleAdd(role_id, role_vo) self:CreateRole(role_vo) end local function roleDel(role_id) self:DeleteRole(role_id) end local function partnerAdd(partner_id, partner_vo) self:CreatePartner(partner_vo) end local function partnerDel(partner_id) self:DeletePartner(partner_id) end local function monsterAdd( ins_id, monster_vo) self:CreateMonster(monster_vo) end local function monsterDel( ins_id) self:DeleteMonster(ins_id) end local function otherAdd( ins_id, other_vo) self:CreateOther(other_vo) end local function otherDel( ins_id) self:DeleteOther(ins_id) end local function door_add(enter_scene_id, vo) self:CreateDoor(vo) end local function jumppoint_add(vo) self:CreateJumpPoint(vo) end local function npc_add(ins_id, vo) self:CreateNpc(vo) end local function waypoint_add(vo) self:CreateWayPoint(vo) end local function delete_npc(id) self:DeleteNpc(id) end local function delete_door(id) self:DeleteDoor(id) end local function delete_jumppoint(id) self:DeleteJumpPoint(id) end local function delete_wappoint(id) self:DeleteWayPoint(id) end local function graveAdd(ins_id, grave_vo) self:CreateGrave(grave_vo) end local function graveDel(ins_id) self:DeleteGrave(ins_id) end local function hookRoleAdd(role_id, role_vo) self:CreateHookRole(role_vo) end local function hookRoleDel(role_id) self:DeleteHookRole(role_id) end local function buildAdd(build_vo) self:CreateBuild(build_vo) end local function buildDel( ins_id) self:DeleteBuild(ins_id) end local function buildBabyAdd(build_baby_vo) self:CreateBuildBaby(build_baby_vo) end local function buildBabyDel( ins_id) self:DeleteBuildBaby(ins_id) end local function furnitureAdd(furniture_vo) self:CreateFurniture(furniture_vo) end local function furnitureDel( ins_id) self:DeleteFurniture(ins_id) end local function sceneLoad(hide_load_progress) self:CancelWaitQuest() --切场景前关掉定时器 self:OpenSceneLoadView(hide_load_progress) end --delay_jump_type 1 攻击后传送 2 攻击后跳跃 local function onMainRoleJump(delay_jump_type) MainCamera.Instance:ChangeSmoothState(MainCamera.SmoothState.Jump) local main_role = Scene.Instance:GetMainRole() if main_role == nil or main_role:IsGhostMode() then return end if main_role.is_shoe_flying then return end if main_role.curr_multi_jump_type == Role.MULTI_JUMP_TYPE.Jump_4 then return end --在跳水的那一下,不能进行跳跃 --预估距离 local distance = nil local jump_type = main_role.curr_multi_jump_type or 1 distance = main_role:GetPredictJumpDistance(jump_type) local dir = SkillManager:getInstance().joy_stick_dir or main_role.direction local dist = distance local end_pos = co.TableXY(main_role.real_pos.x + dir.x * dist, main_role.real_pos.y + dir.y * dist) --[[ 1.根据配置,通过跳跃距离和方向,计算出一个初始跳跃点 point_1 2.检测这个跳跃是否是障碍点,如果不行,找到里这个点最近的跳跃点 point_2 3.根据检测后的 point_2 读取配置参数,计算起跳上升时间和下降时间,求和得出总时间。用垂直总时间矫正水平移动的时间,再次计算水平移动的距离,计算出,3D模式下的最终落点point_3 4.检测point_3是否是障碍点,如果是,矫正位置后传入DoJump() 5.用得出的参数进行跳跃动画计算 6.如果跳跃结束点高度过高,大于跳跃中最高的高度,就不让他跳过去 需要做多次障碍的原因是障碍区的高度值为0,会影响到跳跃动画的计算 ]] --要先计算一次目标点是否可以跳过去 if self.scene_mgr:CannotJumpCrossBlockScene() then end_pos = co.Vector2(SourceOperateMove.FindNearestPos(co.TableXY(main_role.real_pos.x,main_role.real_pos.y), end_pos, false)) elseif self.scene_mgr:IsBlockXY(end_pos.x/SceneObj_LogicRealRatio_x, end_pos.y / SceneObj_LogicRealRatio_y) then end_pos = co.Vector2(SourceOperateMove.FindNearestPos(co.TableXY(main_role.real_pos.x,main_role.real_pos.y), end_pos, false)) end if jump_type == Role.MULTI_JUMP_TYPE.Jump_1 then local ttdistance = GameMath_GetDistance(end_pos.x, end_pos.y, main_role.real_pos.x, main_role.real_pos.y, true) end_pos = main_role:GetJumpEndPos(end_pos,jump_type) local ttdistance2 = GameMath_GetDistance(end_pos.x, end_pos.y, main_role.real_pos.x, main_role.real_pos.y, true) end local lx = end_pos.x / SceneObj_LogicRealRatio_x local ly = end_pos.y / SceneObj_LogicRealRatio_y if self.scene_mgr:CannotJumpCrossBlockScene() then end_pos = co.Vector2(SourceOperateMove.FindNearestPos(co.TableXY(main_role.real_pos.x,main_role.real_pos.y), end_pos, false)) else if self.scene_mgr:IsBlockXY(lx, ly) then local fastPos = co.Vector2(SourceOperateMove.FindFastestPos(co.TableXY(main_role.real_pos.x,main_role.real_pos.y), end_pos)) if self.scene_mgr:IsBlockXY(fastPos.x / SceneObj_LogicRealRatio_x,fastPos.y / SceneObj_LogicRealRatio_y) then end_pos = SourceOperateMove.FindNoBlockPos(main_role.logic_pos) --如果跳跃的位置是不可行走区域,就找到最近的一个可行走点,跳过去 end_pos.x = end_pos.x * SceneObj_LogicRealRatio_x end_pos.y = end_pos.y * SceneObj_LogicRealRatio_y else end_pos = fastPos end end local end_height = Scene.Instance:GetZoneHeight(end_pos.x/SceneObj_LogicRealRatio_x, end_pos.y/ SceneObj_LogicRealRatio_y) --落地点的高度 local a = Config.otherFightInfo.jump_gravity_speed[jump_type] local upTime = Config.otherFightInfo.jump_vspeed[jump_type][1] / a -- 上升时间 local max_height = 0.5 * a * upTime * upTime + main_role.jump_height+main_role.obj_pos_height*100 --最大跳跃高度 1/2 at2 if end_height*100 > max_height then end_pos = co.Vector2(SourceOperateMove.FindNearestPos(co.TableXY(main_role.real_pos.x,main_role.real_pos.y), end_pos, false)) end end main_role:DoJump(end_pos,nil,nil,nil,nil,jump_type,false,false,false,false,false,false,delay_jump_type) SkillManager:getInstance().joy_stick_dir = nil end local function onMainRoleJumpEnd(force_check, logic_x, logic_y) local main_role = self.main_role if main_role then if main_role.move_flag and main_role.move_flag == MOVE_TYPE.ACCELERATE then MainCamera.Instance:ChangeSmoothState(MainCamera.SmoothState.NewBieTask) else MainCamera.Instance:ChangeSmoothState(MainCamera.SmoothState.Normal) end end self:CheckJumpPoint(force_check, logic_x, logic_y) self:CheckDoorInSameScene(true) end local function onMainRoleMoveEnd() if not self.check_jump_point_time then self:CheckJumpPoint() self.check_jump_point_time = Status.NowTime else if Status.NowTime - self.check_jump_point_time > Config.otherFightInfo.check_jump_point_space then self:CheckJumpPoint() self.check_jump_point_time = Status.NowTime end end end local function onRoleTaskJump(end_pos,call_back,move_vspeed,role, force_jump) MainCamera.Instance:ChangeSmoothState(MainCamera.SmoothState.TaskJump) local role = role or Scene.Instance:GetMainRole() if role == nil then return end if role.is_shoe_flying then return end if role:IsInState(PoseState.TASK_JUMP) and not force_jump then return end local distance = GameMath_GetDistance(role.real_pos.x,role.real_pos.y,end_pos.x,end_pos.y,true) local dir = CoVector2.New(end_pos.x - role.real_pos.x ,end_pos.y - role.real_pos.y) dir:normalise() --跳跃次数 local count_cfg = Config.otherFightInfo.shoe_muiti_jump_info local need_count = 0 for i=1,#count_cfg do if distance >= count_cfg[i].min and distance <= count_cfg[i].max then need_count = count_cfg[i].jump_counts break end end --如果是强制跳跃,那就让他一段跳 if need_count == 0 and force_jump then need_count = 1 end if need_count == 0 then local findVo = FindVo.New() findVo.type = FindVo.POINT findVo.sceneId = SceneManager.Instance:GetSceneId() findVo.x = end_pos.x / SceneObj.LogicRealRatio.x findVo.y = end_pos.y / SceneObj.LogicRealRatio.y findVo.call_back = call_back GlobalEventSystem:Fire(EventName.STOPAUTOFIGHT) Scene:getInstance():FindElement(findVo) else local target_list = {} if need_count == 1 then target_list = { [1] = co.TableXY(end_pos.x,end_pos.y), } elseif need_count == 2 then target_list = { [1] = co.TableXY(role.real_pos.x + dir.x * distance / 2,role.real_pos.y + dir.y * distance / 2), [2] = co.TableXY(end_pos.x,end_pos.y), } elseif need_count == 3 then target_list = { [1] = co.TableXY(role.real_pos.x + dir.x * distance / 3,role.real_pos.y + dir.y * distance / 3), [2] = co.TableXY(role.real_pos.x + dir.x * distance / 3 * 2,role.real_pos.y + dir.y * distance / 3 * 2), [3] = co.TableXY(end_pos.x,end_pos.y), } end GlobalEventSystem:Fire(EventName.CANCEL_SPEED_BUFF) role:DoTaskJump(Role.MULTI_JUMP_TYPE.Jump_2, target_list,call_back,move_vspeed,true) end end local function onRoleGameFlyJump(jump_time,start_pos, end_pos, role, call_back, is_fail) MainCamera.Instance:ChangeSmoothState(MainCamera.SmoothState.Jump) local main_role = role or Scene.Instance:GetMainRole() if main_role == nil then return end local distance = nil local dir = main_role.direction local dist,move_hspeed,move_vspeed = main_role:GetGameJumpDistanceAndSpeed(jump_time) local end_pos = co.TableXY(main_role.real_pos.x + dir.x * dist, main_role.real_pos.y + dir.y * dist) local start_pos = co.TableXY(main_role.real_pos.x, main_role.real_pos.y) main_role:DoGameFlyJump(end_pos,start_pos,move_hspeed,move_vspeed,call_back,is_fail) end local function onMainRoleMove() if not self.check_jump_point_time then self:CheckJumpPoint() self.check_jump_point_time = Status.NowTime else if Status.NowTime - self.check_jump_point_time > Config.otherFightInfo.check_jump_point_space then self:CheckJumpPoint() self:CheckSkyBoxArea() self:CheckDoorInSameScene() self.check_jump_point_time = Status.NowTime end end end local function reset_fun(logic_x, logic_y, is_dir_move) if AutoFightManager.Instance.go_to_pos and AutoFightManager:getInstance():GetAutoFightState() then AutoFightManager:getInstance():CacheGoToPos() end if not self:CheckJumpPoint(nil, logic_x, logic_y) then if not is_dir_move then OperateManager.Instance:StopMove() end end end local function onMainRoleJumpEndImm() if AutoFightManager:getInstance():GetAutoFightState() then self:UpdateAutoFight(true) end end local function onSceneChange() local id = SceneManager:getInstance():GetSceneId() if Config.ConfigDoorInSameScene[id] then self.has_same_scene_door = true else self.has_same_scene_door = false end if not self.is_set_frame_rate then self.is_set_frame_rate = true setTimeout(function() SetGameFrameRate() end,10) end -- self:ChangeMainRoleScale() -- local need_check -- local scene_info = self.scene_mgr:GetSceneInfo() -- if scene_info then -- if Config.ConfigSceneDangerEffect.Type[scene_info.type] and self.scene_mgr:IsShowDangerWarnScene() then -- need_check = true -- if not self.bind_hp_handler then -- local function onHpChange() -- if RoleManager.Instance.mainRoleInfo.hp / RoleManager.Instance.mainRoleInfo.maxHp < 0.3 then -- EventSystem.Fire(GlobalEventSystem,EventName.PLAY_DANGER_EFFECT, true) -- else -- EventSystem.Fire(GlobalEventSystem,EventName.PLAY_DANGER_EFFECT, false) -- end -- end -- self.bind_hp_handler = RoleManager.Instance.mainRoleInfo:BindOne("hp", onHpChange) -- onHpChange() -- end -- end -- end -- if not need_check then -- EventSystem.Fire(GlobalEventSystem,EventName.PLAY_DANGER_EFFECT, false) -- if self.bind_hp_handler then -- RoleManager.Instance.mainRoleInfo:UnBind(self.bind_hp_handler) -- self.bind_hp_handler = nil -- end -- end -- local playerLv = RoleManager:getInstance():GetMainRoleVo().level -- if playerLv > 85 and not SystemRuntimePlatform.IsIphone() then -- SceneDropManager:getInstance():CreateDropEffectToPool() -- end end GlobalEventSystem:Bind(SceneEventType.MAIN_ROLE_MOVE_TO_BLOCK, reset_fun) --移动至障碍区 GlobalEventSystem:Bind(SceneEventType.DOOR_VO_ADD, door_add) --传送门增加 GlobalEventSystem:Bind(SceneEventType.DOOR_VO_REMOVE, delete_door) --传送门移除 GlobalEventSystem:Bind(SceneEventType.JUMPPOINT_VO_ADD, jumppoint_add) --跳点增加 GlobalEventSystem:Bind(SceneEventType.JUMPPOINT_VO_REMOVE, delete_jumppoint) --跳点移除 GlobalEventSystem:Bind(SceneEventType.NPC_VO_ADD, npc_add) --npc增加 GlobalEventSystem:Bind(SceneEventType.NPC_VO_REMOVE, delete_npc) --npc移除 GlobalEventSystem:Bind(SceneEventType.ROLE_VO_ADD, roleAdd) --角色增加 GlobalEventSystem:Bind(SceneEventType.ROLE_VO_REMOVE, roleDel) --角色移除 GlobalEventSystem:Bind(SceneEventType.PARTNER_VO_ADD, partnerAdd) --伙伴增加 GlobalEventSystem:Bind(SceneEventType.PARTNER_VO_REMOVE, partnerDel) --伙伴移除 GlobalEventSystem:Bind(SceneEventType.MONSTER_VO_ADD, monsterAdd) --怪物增加 GlobalEventSystem:Bind(SceneEventType.MONSTER_VO_REMOVE, monsterDel) --怪物移除 GlobalEventSystem:Bind(SceneEventType.OTHER_VO_ADD, otherAdd) --普通场景对象增加 GlobalEventSystem:Bind(SceneEventType.OTHER_VO_REMOVE, otherDel) --普通场景对象移除 GlobalEventSystem:Bind(SceneEventType.OPEN_SCENE_LOAD_VIEW, sceneLoad) --打开场景加载页 GlobalEventSystem:Bind(SceneEventType.MAIN_ROLE_JUMP, onMainRoleJump) --主角跳跃 GlobalEventSystem:Bind(SceneEventType.MAIN_ROLE_JUMP_END, onMainRoleJumpEnd) --跳跃结束 GlobalEventSystem:Bind(SceneEventType.MAIN_ROLE_JUMP_END_IMM, onMainRoleJumpEndImm) --跳跃结束 GlobalEventSystem:Bind(ObjectEventType.MAINROLE_MOVE_EVENT_IMME,onMainRoleMove) --主角移动 GlobalEventSystem:Bind(SceneEventType.MAIN_ROLE_MOVE_END, onMainRoleMoveEnd) --移动结束 GlobalEventSystem:Bind(SceneEventType.CREATE_WAY_POINT, waypoint_add) --寻路点增加 GlobalEventSystem:Bind(SceneEventType.DELETE_WAY_POINT, delete_wappoint) --寻路点移除 GlobalEventSystem:Bind(SceneEventType.GRAVE_VO_ADD, graveAdd) --墓碑增加 GlobalEventSystem:Bind(SceneEventType.GRAVE_VO_REMOVE, graveDel) --墓碑移除 GlobalEventSystem:Bind(SceneEventType.HOOK_VO_ADD, hookRoleAdd) --挂机角色增加 GlobalEventSystem:Bind(SceneEventType.HOOK_VO_REMOVE, hookRoleDel) --挂机角色移除 GlobalEventSystem:Bind(SceneEventType.BUILD_VO_ADD, buildAdd) --家园建筑增加 GlobalEventSystem:Bind(SceneEventType.BUILD_VO_REMOVE, buildDel) --家园建筑移除 GlobalEventSystem:Bind(SceneEventType.FURNITURE_VO_ADD, furnitureAdd) --家具增加 GlobalEventSystem:Bind(SceneEventType.FURNITURE_VO_REMOVE, furnitureDel) --家具移除 GlobalEventSystem:Bind(EventName.SCENE_LOAD_VIEW_COMPLETE, onSceneChange) --场景加载页完成 GlobalEventSystem:Bind(SceneEventType.BUILD_BABY_VO_ADD, buildBabyAdd) --建筑宝宝增加 GlobalEventSystem:Bind(SceneEventType.BUILD_BABY_REMOVE, buildBabyDel) --建筑宝宝移除 GlobalEventSystem:Bind(SceneEventType.TASK_MUL_JUMP, onRoleTaskJump) --任务跳跃 GlobalEventSystem:Bind(SceneEventType.GAME_FLY_JUMP, onRoleGameFlyJump) --游戏跳跃 local function hide_all_mon() self.is_hide_all_mon = true self:UpdateAllMonsterVisible() end local function show_all_mon() self.is_hide_all_mon = nil self:UpdateAllMonsterVisible() end GlobalEventSystem:Bind(SceneEventType.HIDE_ALL_MONSTER, hide_all_mon) GlobalEventSystem:Bind(SceneEventType.SHOW_ALL_MONSTER, show_all_mon) local function hide_all_role() self.is_hide_all_role = true self:UpdateRoleVisibleState(true) end local function show_all_role() self.is_hide_all_role = nil self:UpdateRoleVisibleState(true) end GlobalEventSystem:Bind(SceneEventType.HIDE_ALL_ROLE, hide_all_role) GlobalEventSystem:Bind(SceneEventType.SHOW_ALL_ROLE, show_all_role) local function onBlockSettingChange(key, value) --处于性能考虑 这几个可以立马生效 其他的 只有重新创建的时候才生效 不屏蔽主角的 if key == "wing" then -- 炫翼 for _, v in pairs(self.role_list) do if v ~= self.main_role then if v.ChangeWing then v:ChangeWing() end end end for _, v in pairs(self.hook_role_list) do if v.ChangeWing then v:ChangeWing() end end elseif key == "talisman" then -- 宝具 for _, v in pairs(self.role_list) do if v.ChangeSprite then v:ChangeSprite() end end elseif key == "headwear" then for _, v in pairs(self.role_list) do if v ~= self.main_role then if v.ChangeHeadWear then v:ChangeHeadWear() end end end elseif key == "aiNiang" then --ai娘 for _, v in pairs(self.role_list) do if v ~= self.main_role then if v.ChangePet then v:ChangePet() end end end elseif key == "godWeapon" then -- 武器 for _, v in pairs(self.role_list) do if v ~= self.main_role then if v.ChangeWeapon then v:ChangeWeapon() end end end elseif key == "baby" then for _, v in pairs(self.role_list) do if v ~= self.main_role then if v.ChangeBaby then v:ChangeBaby() end end end elseif key == "title" then -- 称号 for _, v in pairs(self.role_list) do if v ~= self.main_role then --没有使用ChangeDsgt是因为nameboard里面把子节点隐藏了,所以ChangeDsgt不够哟 if v.UpdateDsgt then v:UpdateDsgt() end end end elseif key == "active" then for _, v in pairs(self.role_list) do if v ~= self.main_role then if v.ShowLivenessImage then v:ShowLivenessImage() end end end elseif key == "pet" then -- 宠物 for _, v in pairs(self.role_list) do if v ~= self.main_role then if v.ChangePokemonId then v:ChangePokemonId() end end end elseif key == "horse" then -- 座驾 for _, v in pairs(self.role_list) do if v ~= self.main_role then if v.ChangeHorse then v:ChangeHorse() end end end elseif key == "scenePtc" then lua_settingM:SetSceneEffect(value) elseif key == "shadow" then -- 实时阴影效果 if self.main_role then self.main_role:ChangeDynamicShadowState() end end end lua_settingM:Bind(GameSettingManager.BLOCK_SETTING_CHANGE, onBlockSettingChange) local function onMonsterDeadHandler(id) self.scene_mgr:DeleteMonsterVo(id, SceneManager.DELETE_MONSTER_DEAD) end GlobalEventSystem:Bind(ObjectEventType.OBJ_DEAD, onMonsterDeadHandler) --尸体渐隐结束的回调 local function deadbody_fade_end_func(deadbody_id) self:DeleteDeadBody(deadbody_id) end GlobalEventSystem:Bind(ObjectEventType.OBJ_DEADBODY_FADE_END, deadbody_fade_end_func) local function roleWalkCompleteHandler() self:RoleWalkCompleteHandler(true) end GlobalEventSystem:Bind(SceneEventType.MAIN_ROLE_MOVE_END, roleWalkCompleteHandler) local function start_check_collect_btn(bool,limit_id_list) if bool then self.check_collect_btn_limit_list = limit_id_list if not self.check_collect_id then local function check_clock() self:CheckMainUICollectBtnState() end self.check_collect_id = GlobalTimerQuest:AddPeriodQuest(check_clock,1,-1) end else if self.check_collect_id then GlobalTimerQuest:CancelQuest(self.check_collect_id) self.check_collect_id =nil end GlobalEventSystem:Fire(EventName.SHOW_MAINUI_COLLECT_BTN,false) end end GlobalEventSystem:Bind(EventName.CHECK_COLLECT_BTN, start_check_collect_btn) local function onSceneStart() if not self.click_target_effect then self:CreateClickTargetEffect() end if self.find_vo_cache then self.find_vo_cache = nil end GlobalEventSystem:Fire(EventName.SHOW_MAINUI_COLLECT_BTN, false) end GlobalEventSystem:Bind(SceneManager.START,onSceneStart) --创建掉落列表 local function onRefreshDropList(vo) local sid = self.scene_mgr:GetSceneId() if vo and vo.map_id == sid then self:RefreshDropList(vo) end end GlobalEventSystem:Bind(SceneEventType.BROADCAST_SCENE_DROP_LIST, onRefreshDropList) local function onUpdateRoleLimitHandler() self:UpdateRoleVisibleState(true) end GlobalEventSystem:Bind(SceneEventType.UPDATE_ROLE_LIMIT, onUpdateRoleLimitHandler) local function findway_ended_func() self:ClearLastAttack() -- DialogueModel:getInstance():SetMultSelectTaskID(nil) end GlobalEventSystem:Bind(EventName.FINDWAY_ENDED, findway_ended_func) -- local function onCancelClickTarget() -- end -- GlobalEventSystem:Bind(SceneEventType.CANCEL_CLICK_TARGET, onCancelClickTarget) local function onCamareMoveHandler() --摄像机移动时,主角停止移动时,更新名字条位置 if self.main_role then local x,y = self.main_role:GetRealPos() local mainrole_height = self.main_role.obj_pos_height if not self.main_role:IsGhostMode() then self.main_role.name_board:UpdatePos(x,y,mainrole_height) end end self.nameBoard_mgr:UpdateAllNameBoard() end EventSystem.Bind(GlobalEventSystem,SceneEventType.CAMERA_MOVE,onCamareMoveHandler) local function onScreenMousePress() if SceneManager.Instance:IsSceneStart() then local main_role = Scene.Instance:GetMainRole() if main_role then main_role.stand_init_time = 0 end end end EventSystem.Bind(GlobalEventSystem,GameInputManager.GameInputEvent.MOUSE_PRESS, onScreenMousePress) local function onPkStatusChangeHandler() --改变模式 当前的对象可能变成不可攻击的 local defender = self.curr_click_target if defender and defender:GetVo() then local attacker_vo = RoleManager.Instance:GetMainRoleVo() local defender_vo = defender:GetVo() if not SceneManager.Instance:CanPKByPKStatus(attacker_vo,defender_vo) then GlobalEventSystem:Fire(EventName.SHOW_OTHER_HEAD,false) self:CancelClickTarget() end end end RoleManager.Instance.mainRoleInfo:BindOne("pk_status", onPkStatusChangeHandler) --只有主角的需要,因为可能地图没加载完就去设置位置,可能是障碍区 -- local function onSceneMapLoadCompleted() -- if self.main_role then -- self.main_role:SetFollowObjPosition() -- end -- end -- EventSystem.Bind(GlobalEventSystem,EventName.LOADMAP_COMPLETE,onSceneMapLoadCompleted) local load_npc_finish = function() self.load_npc_finish = true end GlobalEventSystem:Bind(EventName.NPC_LOAD_FINISH,load_npc_finish) if not self.write_cache_file_timer and tonumber(AppConst.EnglineVer) >= 77 then local write_func = function() local mainrole = Scene.Instance:GetMainRole() if mainrole and mainrole:IsInState(PoseState.ATTACK) then return end local cache_count = resMgr:GetDownloadCacheFileCount() if cache_count > 0 then resMgr:WriteDownloadCacheFile() end end self.write_cache_file_timer = TimerQuest.AddPeriodQuest(GlobalTimerQuest, write_func, 2, -1) end local function dun_drop_all_list( ... )--结算的时候收纳所有掉落道具 local goods_data = {} for _, v in pairs(self.drop_list) do if v.state ~= 4 then v.state = 4--飞到角色身上 v.not_fly_float = true--这里不需要单个飘字 goods_data[#goods_data + 1] = {goods_type_id = v.vo.type_id,num = v.vo.drop_num} end end if #goods_data > 0 then MainUIModel:getInstance():AddFloatInfo(goods_data,true) end end GlobalEventSystem:Bind(BaseDungeonModel.FINISH_DROP_LIST, dun_drop_all_list) --守护拾取检测 local on_check_evil_auto_pick = function() if not self.only_main_role_pick and not SceneManager:getInstance():IsGuildScene() and ItemUseModel:getInstance():HasWearEvil() and self.main_role and self.main_role.evil then self:OnEvilPick() end end GlobalEventSystem:Bind(EventName.EVIL_AUTO_PICK,on_check_evil_auto_pick) --一键拾取过程中 local onUpdatePickAllDropState = function(state) self.is_in_pick_all_state = state print('Ych:Scene.lua[968] data', self.is_in_pick_all_state) end GlobalEventSystem:Bind(EventName.UPDATE_PICK_ALL_DROP_STATE,onUpdatePickAllDropState) end --[[ res_name: 资源名字 need_select: 加载完特效,是否选中当前目标 ]] function Scene:CreateClickTargetEffect(res_name, need_select) local effect_name = res_name or "mrsd_xuanzhong_001" self.effect_res = effect_name --用于判断是否需要加载其他特效 local function load_call_back(objs, is_gameObject) if objs and objs[0] then self.click_target_effect = is_gameObject and objs[0] or newObject(objs[0]) self.click_target_effect:SetActive(false) if need_select then self:SetClickTarget(self.curr_click_target, true) else if self.main_role and not IsNull(self.main_role.parent_transform) then self.click_target_effect.transform:SetParent(self.main_role.parent_transform) end end end end lua_resM:loadPrefab(self,effect_name,effect_name, load_call_back) end --传送点在同一个场景里的传送门 function Scene:CheckDoorInSameScene(fire_evt) if not self.has_same_scene_door then return end local main_role = Scene.Instance:GetMainRole() local dist = dist or 2 local near_door = nil local cfg = Config.ConfigDoorInSameScene[SceneManager:getInstance():GetSceneId()] if cfg then local posX,posY = self.main_role:GetLogicPos() local door_posX = 0 local door_posY = 0 for i,door in pairs(cfg) do door_posX = door.x / SceneObj_LogicRealRatio_x door_posY = door.y / SceneObj_LogicRealRatio_y if GameMath_IsPointNear(posX, posY, door_posX, door_posY, dist) then near_door = door do break end end end if near_door then if fire_evt then self:RoleWalkCompleteHandler(true) else OperateManager.Instance:StopMove() end end end end function Scene:CheckSkyBoxArea() local area_info = Config.SkyBoxAreaInfo[self.scene_mgr:GetSceneId()] if area_info then local x, y = self.main_role:GetRealPos() for i, vo in ipairs(area_info) do local dis = GameMath_GetDistance(x, y, vo.center_pos.x, vo.center_pos.y, true) if dis < vo.range and (not vo.task_list or TaskModel.getInstance():IsBetweenTaskListState(vo.task_list)) then if not self.is_showing_sky_box then local cfg = { black_ground_alpha = vo.black_ground_alpha, show_type = vo.black_ground_show_type, sky_res = vo.black_ground_sky_res, show_target_alpha = vo.show_target_alpha, show_step_alpha = vo.show_step_alpha, hide_target_alpha = vo.hide_target_alpha, hide_step_alpha = vo.hide_step_alpha, } MainCamera.getInstance():ShowBlackSky(cfg.sky_res, cfg.show_target_alpha, cfg.show_step_alpha) self.is_showing_sky_box = cfg end break else if self.is_showing_sky_box then MainCamera.getInstance():HideBlackSky(self.is_showing_sky_box.sky_res, self.is_showing_sky_box.hide_target_alpha, self.is_showing_sky_box.hide_step_alpha) self.is_showing_sky_box = false end end end end end function Scene:CheckJumpPoint(force_check,role_id) local main_role = role_id and self:GetRole(role_id) or self.main_role if main_role == nil or main_role:IsGhostMode() then return false end local scene_info = Config.MultiJumpPos[self.scene_mgr:GetSceneId()] local x, y = main_role:GetRealPos() local function on_task_jump( ) if scene_info then for j, pvo in ipairs(scene_info) do for i, vo in ipairs(pvo) do local range = vo.range * vo.range local check_cd_time = vo.jump_show_type == 2 and 1 or 5 if (not main_role.jump_curr_trigger_index or main_role.jump_curr_trigger_index == j) and GameMath_GetDistance(x, y, vo.start_pos.x, vo.start_pos.y, false) <= range and not main_role:IsInState(PoseState.FLY_SHOE_EFFECT) and not main_role:IsInState(PoseState.TaskJump) then -- if vo.trigger_time then -- print("tanar: [Scene 1069]=> i : ",i, Status.NowTime - vo.trigger_time) -- end if vo.trigger_time == nil or Status.NowTime - vo.trigger_time > check_cd_time then main_role.jump_curr_trigger_index = j vo.trigger_time = Status.NowTime if vo.jump_show_type == 2 then main_role:DoFlyShoeEffect(vo.middle_pos, 3) else GlobalEventSystem:Fire(SceneEventType.TASK_MUL_JUMP,vo.middle_pos,nil,nil, nil , true) end return true end end end end end end if on_task_jump() then return true end local lx, ly = main_role:GetLogicPos() --如果是跳点区域 或者 local is_jump = self.scene_mgr:IsAreaType(lx, ly, AreaDataIndex.JumpType) --上一个区域跳跃结束点是障碍点 local next_jump_is_block = force_check and self.scene_mgr:IsBlockXY(lx, ly) and main_role:IsInState(PoseState.TASK_JUMP) if is_jump or next_jump_is_block then if force_check then local nearest_end_pos, nearest_end_dis = nil, nil -- print("tanar: [Scene 1096]=> is_jump: ",is_jump) if is_jump then on_task_jump() elseif next_jump_is_block then local unblock_pos = SourceOperateMove.FindNoBlockPos(main_role.logic_pos) if unblock_pos then nearest_end_pos = co_TableXY(unblock_pos.x * SceneObj_LogicRealRatio_x, unblock_pos.y * SceneObj_LogicRealRatio_y) else return false end else return false end if nearest_end_pos then GlobalEventSystem:Fire(SceneEventType.TASK_MUL_JUMP, nearest_end_pos, nil, nil, nil, true) end --[[ local end_pos = nil local multi_jump = false if is_jump then local distance = nil distance = main_role:GetPredictJumpDistance(main_role.curr_multi_jump_type or 1) local dir = main_role.direction local dist = distance or 800 end_pos = co.TableXY(main_role.real_pos.x + dir.x * dist, main_role.real_pos.y + dir.y * dist) lx = end_pos.x / SceneObj_LogicRealRatio_x ly = end_pos.y / SceneObj_LogicRealRatio_y if self.scene_mgr:IsBlockXY(lx, ly) then local ex, ey, result = SourceOperateMove.FindFastestPos(co.TableXY(main_role.real_pos.x,main_role.real_pos.y), end_pos) if result then end_pos = co.Vector2(ex, ey) -- elseif self.scene_mgr:IsAreaType(lx, ly, AreaDataIndex.JumpType) then else main_role:CancelSmoothHeight(); multi_jump = true end end elseif next_jump_is_block then local unblock_pos = SourceOperateMove.FindNoBlockPos(main_role.logic_pos) if unblock_pos then end_pos = co.TableXY(unblock_pos.x * SceneObj_LogicRealRatio_x, unblock_pos.y * SceneObj_LogicRealRatio_y) multi_jump = false else return false end else return false end self.last_multi_jump_time = Status.NowTime -- main_role:DoJump(end_pos, true) GlobalEventSystem:Fire(SceneEventType.TASK_MUL_JUMP, end_pos, nil, nil, nil, true) if multi_jump then if main_role.jump_info then main_role.jump_area_mutil_jump_end_time = Status.NowTime + main_role.jump_info.move_time * 0.85 end else main_role.jump_area_mutil_jump_end_time = nil end ]] end main_role:CancelSmoothHeight() return true end return false end function Scene:InitSAPFunction() local func = function(operate,obj_type,obj_data) if operate == SapManager.OperateType.CreateOBJ then if obj_type == SapManager.ObjType.JumpPoint then local jumppoint_vo = obj_data local jumppoint = JumpPoint.New(jumppoint_vo) self.jumppoint_list[jumppoint.id] = jumppoint elseif obj_type == SapManager.ObjType.Door then local door = Door.New(obj_data) if obj_data.is_same_scene then self.door_list[obj_data.enter_scene_id.."-"..obj_data.index] = door else self.door_list[obj_data.enter_scene_id] = door end elseif obj_type == SapManager.ObjType.NPC then if not self.npc_list[tonumber(obj_data.instance_id)] then local npc_obj = self.npc_pool:GetObjFreeList() if not npc_obj then npc_obj = Npc.New() end npc_obj:InitNpc(obj_data) self.npc_list[tonumber(obj_data.instance_id)] = npc_obj end elseif obj_type == SapManager.ObjType.Tile then self.mapView:CreateTile(obj_data) elseif obj_type == SapManager.ObjType.Effect then self.mapView:CreateEffect(obj_data) elseif obj_type == SapManager.ObjType.Model then self.mapView:CreateModel(obj_data) elseif obj_type == SapManager.ObjType.MoveObj then self.mapView:CreateMoveObj(obj_data) elseif obj_type == SapManager.ObjType.SpecialModel then self.mapView:CreateSpecialModel(obj_data) elseif obj_type == SapManager.ObjType.CacheEffect then self.mapView:CreateCacheEffect(obj_data) end elseif operate == SapManager.OperateType.DestoryOBJ then if obj_type == SapManager.ObjType.JumpPoint then local jumopoint = self.jumppoint_list[obj_data] if jumopoint ~= nil then jumopoint:DeleteMe() self.jumppoint_list[obj_data] = nil end elseif obj_type == SapManager.ObjType.Door then local door = self.door_list[obj_data] if door ~= nil then door:DeleteMe() self.door_list[obj_data] = nil end elseif obj_type == SapManager.ObjType.NPC then local npc = self.npc_list[obj_data] if npc ~= nil then self.npc_pool:ReleaseObj(npc) self.npc_list[obj_data] = nil end elseif obj_type == SapManager.ObjType.Tile then self.mapView:DeleteTile(obj_data) elseif obj_type == SapManager.ObjType.Effect then self.mapView:DeleteEffect(obj_data) elseif obj_type == SapManager.ObjType.Model then self.mapView:DeleteModel(obj_data) elseif obj_type == SapManager.ObjType.MoveObj then self.mapView:DeleteMoveObj(obj_data) elseif obj_type == SapManager.ObjType.SpecialModel then self.mapView:DeleteSpecialModel(obj_data) elseif obj_type == SapManager.ObjType.CacheEffect then self.mapView:DeleteCacheEffect(obj_data) end end end SapManager:getInstance():RegisterCallbackFunc(func) end function Scene:RefreshDropList(vo) local drop_list = vo.drop_list if drop_list then local len = #drop_list if len > 0 then local new_item for i = 1,len do drop_list[i].boss_type = vo.boss_type self:CreateDropObj(drop_list[i],vo.pos_x,vo.pos_y) end end end end function Scene:OpenAutoLoadView(last_time, need_bind_event) if self.sceneLoadView then self.sceneLoadView:AutoToShow(last_time, need_bind_event) end end function Scene:OpenSceneLoadView(hide_load_progress, scene_id, need_black_screen) if UserMsgAdapter.Instance:GetIsAutoConnecting() then hide_load_progress = true UserMsgAdapter.Instance:SetIsAutoConnecting(false) end if self.scene_mgr:NoLoadingViewScene() then ChangeSceneMovie.getInstance():TryOpen() else if self.sceneLoadView and self.sceneLoadView:HasOpen() then return end if not self.sceneLoadView then self.sceneLoadView = SceneLoadView.New() end self.sceneLoadView:Open(hide_load_progress, scene_id, need_black_screen) end end function Scene:CloseSceneLoadView() if self.sceneLoadView and self.sceneLoadView:HasOpen() then self.sceneLoadView:Close() --进入游戏场景有再允许静默重连 if not self.is_first_change_scene then self.is_first_change_scene = true ClientConfig.is_ban_auto_connect = false end end end function Scene:SceneLoadingEnter(sceneId) print("tanar: [Scene 1269]=> sceneId: ",sceneId) self:ChangeScene(sceneId) end function Scene:ChangeScene( sceneId ) self.curr_click_target = false self.manual_target = false self.is_clearing = false self.preload_res_is_loaded = false self.scene_data_loaded = false self.startFocus = true self.load_npc_finish = false self.load_progress_finished = false self.is_in_pick_all_state = false local time = Status.NowTime local load_effect_finish = function( step ) if self.sceneLoadView then self.sceneLoadView:RealUpdateProgress(step, 1, SceneLoadView.LOAD_SCENE_TITLE) end end local load_map_func = function() self:SceneDataLoadCompleted() end self.mapView:Load(sceneId, load_map_func, load_effect_finish ) if self.sceneLoadView then if not self.sceneLoadView.is_first_show then self:CheckToPreLoad() else local function onOpenCallback() self:CheckToPreLoad() end self.sceneLoadView:SetOpenCallBackFunc(onOpenCallback) end end end function Scene:CheckToPreLoad() self.scene_change_start_time = Status.NowTime local scene_info = self.scene_mgr:GetSceneInfo() self:PreLoadSceneObjRes(scene_info) end function Scene:PreLoadSceneObjRes(scene_info) --播放场景背景音乐 local cur_scene = self.scene_mgr:GetSceneId() lua_soundM:PlayBackground(cur_scene, true) --无缝加载的场景不走预加载流程 if self.scene_mgr:NoLoadingViewScene() then self.preload_res_is_loaded = true self.load_progress_finished = true GlobalEventSystem:Fire(SceneEventType.REQUEST_SCENE_INFO) return end --清理Scene类的资源引用 lua_resM:clearReference(self) --重置艺术字缓存池 WorldArtFontManager:getInstance():InitCacheList() --删除不属于当前角色的静态职业技能资源,最多检测8个职业 local main_role_vo = RoleManager.Instance:GetMainRoleVo() local career = main_role_vo.career local sex = main_role_vo.sex for i = 1, 4 do for j = 1,2 do if not (i == career and j == sex) then lua_resM:RemoveStaticObj(i.."@"..j) end end end --清空所有缓存池对象 lua_resM:ClearAllObjPool() --写入静默下载缓存的版本数据 if tonumber(AppConst.EnglineVer) > 83 and StepPackModule.Instance.max_download_speed then Util.AutoWriteVersionFile(9999) end --写入下载缓存的文件 if tonumber(AppConst.EnglineVer) >= 77 then resMgr:WriteAllDownloadCacheFile() end --执行内存清理 resMgr:CollectAllMemory() if tonumber(AppConst.EnglineVer) >= 77 then resMgr:SetCacheDownloadMode(false) end if SystemMemoryLevel.Cur == SystemMemoryLevel.Low and SystemRuntimePlatform.IsIphone() then if self.sceneLoadView and self.sceneLoadView:HasOpen() then self.sceneLoadView:RealUpdateProgress(1, 1, SceneLoadView.LOAD_PRELOAD_RES) end self.start_preload_sceneObjRes_time = Status.NowTime self:PreLoadSceneObjResCompleted() return end --场景切换时增加协程,提升加载速度 InitResLoadSpeed(3) SetAsyncUpLoadLevel(2) if tonumber(AppConst.EnglineVer) >= 87 then --AppConst.LoadResWaitNextFrame = false end --self.preload_last_time = os.clock() --最多预加载的模型种类数量 local model_count_limit = lua_resM:GetMaxPoolObjCount() * 0.4 --每个种类最多重复预加载的数量 local child_model_count_limit = lua_resM:GetMaxChildPoolObjCount() --需要预加载的场景模型列表 local pre_load_mode_list = {} --需要预加载的ab列表 local pre_load_ab_list = {} --需要预加载的技能id列表 key是技能id value: 0 是动态删除特效资源的技能类型 1 是静态的 2 是职业技能资源 -- local pre_load_skills = {[SkillManager.MonsterBaseSkill_1] = 1,[SkillManager.MonsterBaseSkill_2] = 1} local pre_load_skills = {} --需要预加载的技能图标 local config_list = self.SkillMgr:getCfgInitiativeSkillList() if config_list then for _,id in pairs(config_list) do pre_load_skills[id] = 2 self.config_mgr:GetSkillItem(id) end end --怒气技能 local career_index = career.."@"..sex local anger_skill_id = SkillManager.AngerSkill[career_index] if anger_skill_id then pre_load_skills[anger_skill_id] = 2 end --技能三连击的图标 local three_attacks = SkillManager.ThreeAttackSkills[career_index] if three_attacks then for _, id in pairs(three_attacks) do pre_load_skills[id] = 2 self.config_mgr:GetSkillItem(id) end end --需要预加载的模型总数量 local total_model_count = 0 --主角当前模型预加载 local fashion_model_id, fashion_chartlet_id = main_role_vo:GetRoleClotheTextureId() local mainrole_res = main_role_vo:GetRoleClotheId() if fashion_model_id and fashion_chartlet_id then mainrole_res = fashion_model_id end if mainrole_res then pre_load_mode_list[mainrole_res] = 1 total_model_count = total_model_count + 1 end --需要预加载的特效列表 local effect_res_list = {} --重置怪物缓存池 local obj_count = self.monster_pool:GetObjCount() local obj = nil for i = obj_count, 13 do obj = Monster.New() obj.vo = self.scene_mgr:CreateMonsterVo() self.monster_pool:ReleaseObj(obj) end --重置NPC缓存池 obj_count = self.npc_pool:GetObjCount() for i = obj_count, 2 do obj = Npc.New() obj.vo = NpcVo.New() self.npc_pool:ReleaseObj(obj) end --重置角色缓存池 obj_count = self.role_pool:GetObjCount() for i = obj_count, 8 do obj = Role.New() obj.vo = self.scene_mgr:CreateRoleVo() self.role_pool:ReleaseObj(obj) end --当前预加载的模型种类数量 local curr_model_count = 0 --预加载场景NPC模型,NPC一个就行了 if scene_info and scene_info.Npcs then local obj_cfg = nil for id, _ in pairs(scene_info.Npcs) do obj_cfg = ConfigItemMgr.Instance:GetNpcItem(id) if obj_cfg and obj_cfg.icon > 0 and curr_model_count < model_count_limit then if pre_load_mode_list[obj_cfg.icon] == nil then pre_load_mode_list[obj_cfg.icon] = 0 curr_model_count = curr_model_count + 1 end if pre_load_mode_list[obj_cfg.icon] <= 0 then pre_load_mode_list[obj_cfg.icon] = pre_load_mode_list[obj_cfg.icon] + 1 total_model_count = total_model_count + 1 end end end end --预加载场景怪物ID local pre_load_monster_id_list = {} if scene_info and scene_info.mon then for _, id in ipairs(scene_info.mon) do table_insert(pre_load_monster_id_list, id) end end --新手全息模型 if self.mainrole_vo.level <= 1 then local model_res = self.mainrole_vo.career pre_load_mode_list[model_res] = 1 total_model_count = total_model_count + 1 end --角色落地特效,只有放这里才能够快 table_insert(effect_res_list,"effect_transmit_flydown_L_Toe0") table_insert(effect_res_list,"effect_transmit_flydown_root") --新手流程场景需要预加载的资源 if self.mainrole_vo.level <= 120 then --预加载跳跃点特效 if scene_info then local jump_info = Config.JumpSceneInfo[scene_info.id] if jump_info then table_insert(effect_res_list,"scene_tiaoyue") end end --预加载传送点特效 if scene_info and scene_info.Doors and TableSize(scene_info.Doors) > 0 then table_insert(effect_res_list, Door.ParticleResName) end end --根据需要预加载的怪物ID,确定预加载的怪物模型和特效 local mon_cfg = nil for _, id in ipairs(pre_load_monster_id_list) do mon_cfg = ConfigItemMgr.Instance:GetMonsterDataItem(id) if mon_cfg and mon_cfg.icon > 0 and curr_model_count < model_count_limit then if pre_load_mode_list[mon_cfg.icon] == nil then pre_load_mode_list[mon_cfg.icon] = 0 curr_model_count = curr_model_count + 1 end if pre_load_mode_list[mon_cfg.icon] < child_model_count_limit then pre_load_mode_list[mon_cfg.icon] = pre_load_mode_list[mon_cfg.icon] + 1 total_model_count = total_model_count + 1 end end end --根据需要预加载的技能ID,确定预加载的特效资源 local effect_res_name_list = {} for skill_id, is_static in pairs(pre_load_skills) do local movie_cfg = self.SkillMgr:GetFightSkillMovie(skill_id) if movie_cfg and movie_cfg.particles then for i, p_vo in ipairs(movie_cfg.particles) do if is_static == 1 then lua_resM:AppendStaticObjName(p_vo.res) elseif is_static == 2 then lua_resM:AppendStaticObjName(p_vo.res,career_index) end if not effect_res_name_list[p_vo.res] then effect_res_name_list[p_vo.res] = true table_insert(effect_res_list,p_vo.res) end end end end local load_effect_count = #effect_res_list local load_mode_count = total_model_count local load_complete_effect_count = 0 local load_complete_mode_count = 0 local load_skill_icon_count = 0 local load_complete_skill_icon_count = 0 local has_load_res_count = 0 local load_ab_count = #pre_load_ab_list local load_complete_ab_count = 0 local load_res_total = load_effect_count + load_mode_count + load_ab_count --加载完成回调入口 local function checkHasLoadComplete() if load_complete_effect_count == load_effect_count and load_complete_mode_count == load_mode_count and load_complete_skill_icon_count == load_skill_icon_count and load_complete_ab_count == load_ab_count then self:PreLoadSceneObjResCompleted() end end --场景加载界面设置 if self.sceneLoadView and self.sceneLoadView:HasOpen() then self.sceneLoadView:RealUpdateProgress(1, load_res_total, SceneLoadView.LOAD_PRELOAD_RES) end --记录开始预加载的时间,用于判断加载超时 self.start_preload_sceneObjRes_time = Status.NowTime local load_empty_check = function() checkHasLoadComplete() if self.sceneLoadView and self.sceneLoadView:HasOpen() then self.sceneLoadView:RealUpdateProgress(has_load_res_count, load_res_total, SceneLoadView.LOAD_PRELOAD_RES) end end --预加载特效 local cur_effect_index = 1 local load_effect_func = nil self.pre_pool_effect = {} load_effect_func = function() if cur_effect_index <= load_effect_count then local res = effect_res_list[cur_effect_index] cur_effect_index = cur_effect_index + 1 if res then local function load_call_back(objs, is_gameObject) if self.start_preload_sceneObjRes_time then load_complete_effect_count = load_complete_effect_count + 1 if objs and objs[0] then local effect_go = is_gameObject and objs[0] or newObject(objs[0]) lua_resM:AddObjToPool(self, res, res, effect_go) self.pre_pool_effect[res] = true else logWarn("切场景预加载 ------- 找不到特效资源" .. res) end checkHasLoadComplete() end has_load_res_count = has_load_res_count + 1 if self.sceneLoadView and self.sceneLoadView:HasOpen() then self.sceneLoadView:RealUpdateProgress(has_load_res_count, load_res_total, SceneLoadView.LOAD_PRELOAD_RES) end setTimeout(load_effect_func,0.01) end local ignore_pool = true if lua_resM.static_obj_name_list[res] then ignore_pool = false end lua_resM:loadPrefab(self, res, res, load_call_back, ignore_pool) else load_complete_effect_count = load_complete_effect_count + 1 has_load_res_count = has_load_res_count + 1 load_empty_check() setTimeout(load_effect_func,0.01) end end end --预加载模型 local temp_load_mode_list = {} for res, count in pairs(pre_load_mode_list) do for i=1,count do table_insert(temp_load_mode_list,res) end end local cur_model_index = 1 local load_model_func = nil load_model_func = function() if cur_model_index <= load_mode_count then local res = temp_load_mode_list[cur_model_index] cur_model_index = cur_model_index + 1 local abName, resName = GameResPath.GetModelClotheRes(nil, res) if abName and resName then local function load_call_back(objs) if self.start_preload_sceneObjRes_time then load_complete_mode_count = load_complete_mode_count + 1 if objs and objs[0] then local mode_go = newObject(objs[0]) SetLocalPosition(mode_go.transform) SetLocalRotation(mode_go.transform) SetLocalScale(mode_go.transform, 1) lua_resM:AddObjToPool(self, abName, resName, mode_go) else logWarn("切场景预加载 ------- 找不到模型资源" .. res) end checkHasLoadComplete() end has_load_res_count = has_load_res_count + 1 if self.sceneLoadView and self.sceneLoadView:HasOpen() then self.sceneLoadView:RealUpdateProgress(has_load_res_count, load_res_total, SceneLoadView.LOAD_PRELOAD_RES) end setTimeout(load_model_func,0.01) end lua_resM:loadPrefab(self, abName, resName, load_call_back, true) else load_complete_mode_count = load_complete_mode_count + 1 has_load_res_count = has_load_res_count + 1 load_empty_check() setTimeout(load_model_func,0.01) end end end --预加载ab local cur_ab_index = 1 local load_ab_func = nil load_ab_func = function() if cur_ab_index <= load_ab_count then local res = pre_load_ab_list[cur_ab_index] local args = Split(res,",") local abName, resName = args[1], args[2] cur_ab_index = cur_ab_index + 1 --print("预加载ad资源",abName,resName) if abName and resName then local function load_call_back(objs) if self.start_preload_sceneObjRes_time then load_complete_ab_count = load_complete_ab_count + 1 if objs and objs[0] then local go = newObject(objs[0]) SetLocalPosition(go.transform) SetLocalRotation(go.transform) SetLocalScale(go.transform, 1) lua_resM:AddObjToPool(self, abName, resName, go) else logWarn("切场景预加载 ------- 找不到ab资源" .. res) end checkHasLoadComplete() end has_load_res_count = has_load_res_count + 1 if self.sceneLoadView and self.sceneLoadView:HasOpen() then self.sceneLoadView:RealUpdateProgress(has_load_res_count, load_res_total, SceneLoadView.LOAD_PRELOAD_RES) end setTimeout(load_ab_func,0.01) end lua_resM:loadPrefab(self, abName, resName, load_call_back, true) else load_complete_ab_count = load_complete_ab_count + 1 has_load_res_count = has_load_res_count + 1 load_empty_check() setTimeout(load_ab_func,0.01) end end end local max_load_count = 12 if SystemMemoryLevel.Cur == SystemMemoryLevel.Low then max_load_count = 6 elseif SystemMemoryLevel.Cur == SystemMemoryLevel.Middle then max_load_count = 8 end for i = 1, max_load_count do load_model_func() load_effect_func() load_ab_func() end end function Scene:IsPreLoadPoolEffect(res) if not self.pre_pool_effect then return false end return self.pre_pool_effect[res] end --预加载成功 function Scene:PreLoadSceneObjResCompleted() if self.start_preload_sceneObjRes_time then self.start_preload_sceneObjRes_time = nil self.preload_res_is_loaded = true GlobalEventSystem:Fire(SceneEventType.REQUEST_SCENE_INFO) end self.is_first_enter_scene = false self.is_first_enter_game = false self.load_scene_timeout_max = false if tonumber(AppConst.EnglineVer) >= 77 and not SystemRuntimePlatform.IsIphone() then resMgr:SetCacheDownloadMode(true) end end --加载完场景数据 function Scene:SceneDataLoadCompleted() InitResLoadSpeed(1) self.scene_data_loaded = true if self.sceneLoadView then self.sceneLoadView:RealUpdateProgress(1, 1, SceneLoadView.LOAD_SCENE_DATA) end self:SetEnterSceneFlag() self.main_camera:InitCameraSetting() if self.startFocus then local vo = self.mainrole_vo if self.main_role then self.main_role:SetRealPos(vo.pos_x,vo.pos_y) self.main_role:DeilyClearTrailRenderer() else self.main_camera:UpdateCameraPosDirect(vo.pos_x,vo.pos_y) end end --每次进场景重新设置一下技能 self.SkillMgr:Fire(SkillManager.UPDATE_SKILL_LIST) GlobalEventSystem:Fire(EventName.LOADMAP_COMPLETE,self.scene_mgr:GetSceneId()) end function Scene:IsSceneLoaded() return self.scene_data_loaded end function Scene:GetClickTarget() return self.curr_click_target end --[[ force: 强制选中 ]] function Scene:SetClickTarget(target, force) if self.curr_click_target == target and not force then return end if self.curr_click_target and self.curr_click_target ~= target then self:CancelClickTarget() end self.curr_click_target = target if target then --小怪显示血条 if target and target.SetHideNameBordOnSelect then target:SetHideNameBordOnSelect(false) end if target and target.SetObjectIsOnSelect then target:SetObjectIsOnSelect(true) end if target:GetType() ~= SceneBaseType.Role then --选中怪物时,就把头像清掉 GlobalEventSystem:Fire(EventName.SHOW_OTHER_HEAD, false) end --挂脚底特效 if IsNull(self.click_target_effect) then destroy(self.click_target_effect) self.click_target_effect = nil if not self.recreate_target_effect then self.recreate_target_effect = true self:CreateClickTargetEffect(nil, true) end return end if lua_viewM.is_lock_screen then if self.click_target_effect.activeSelf then self.click_target_effect:SetActive(false) end else local transform = self.click_target_effect.transform transform:SetParent(target.parent_transform) SetLocalPosition(transform,0,0.1,0) transform.localRotation = Quaternion.Euler(target.rotateX, 0,0) self.click_target_effect:SetActive(true) end end --如果在boss场景, 选中boss的时候就显示血条 if target and self.scene_mgr:IsBossScene() and target:GetType() == SceneBaseType.Monster and target:GetVo() and BossModel:GetInstance():GetIsBossById(target:GetVo().type_id) then GlobalEventSystem:Fire(EventName.SHOW_HITER_BLOOD_VIEW, true, target:GetVo()) end end function Scene:CancelClickTarget(force_select_new_target,force_Cancel) if self.curr_click_target and self.curr_click_target.GetType then if not force_select_new_target and self.manual_target and not self.manual_target:IsDead() and self.manual_target == self.curr_click_target and not force_Cancel then --不取消手选的目标 return end if self.curr_click_target and self.curr_click_target.SetHideNameBordOnSelect then self.curr_click_target:SetHideNameBordOnSelect(true) end if self.curr_click_target and self.curr_click_target.SetObjectIsOnSelect then self.curr_click_target:SetObjectIsOnSelect(false) end if IsNull(self.click_target_effect) then -- destroy(self.click_target_effect) -- self.click_target_effect = nil -- self:CreateClickTargetEffect() else self.click_target_effect:SetActive(false) end --挂机选择目标那里会找不到怪物 if self.manual_target == self.curr_click_target then self.manual_target = false end self.curr_click_target = false self.has_task_target = false GlobalEventSystem:Fire(SceneEventType.CANCEL_CLICK_TARGET) -- if force_select_new_target then -- self:UpdateAutoFindTarget() -- local skill_id = self.SkillMgr:PrepareAutoFightSkill(true) -- if skill_id and type(skill_id) == "number" then -- self.SkillMgr:SetAttackCompleteSkill(skill_id) -- end -- end end end function Scene:UpdateClickTargetEffect() if self.curr_click_target and self.main_role then local real_x, real_y = self.curr_click_target:GetRealPos() local real_pos_x, real_pos_y = self.main_role:GetRealPos() local range if self.scene_mgr:IsGuildScene() then -- 社团场景扩大更新范围 range = 4000*4000 else range = 800 * 800 end if GameMath_GetDistance(real_pos_x, real_pos_y, real_x, real_y, false) > range then self:CancelClickTarget(nil, true) end end ------------------------- --超过一定距离之后,头像消失 local attack_vo = self.scene_mgr:GetAttackHeadVo() if attack_vo and self.main_role then local attack_role = self:GetRole(attack_vo.role_id) if attack_role then local real_x, real_y = attack_role:GetRealPos() local real_pos_x, real_pos_y = self.main_role:GetRealPos() local distance = 800 * 800 if GameMath_GetDistance(real_pos_x, real_pos_y, real_x, real_y, false) > distance then self.scene_mgr:ResetAttackHeadVo(true) end end end ------------------------- end function Scene:OnTouchBegin(x,y) TaskModel:getInstance().circle_use_clock = false--重置跑环界面倒计时 ------------------------- self.touch_bengin_y = nil self.touch_bengin_x = nil --[[ if Input.touchCount == 2 then if self.two_finger_drag_start_pos == nil then self.two_finger_drag_start_pos = {base_dist = GameMath_GetDistance(Input.GetTouch(0).position.x, Input.GetTouch(0).position.y, Input.GetTouch(1).position.x, Input.GetTouch(1).position.y, true), change_state = 0} --0无 1放大 2缩小 else self.two_finger_drag_start_pos.base_dist = GameMath_GetDistance(Input.GetTouch(0).position.x, Input.GetTouch(0).position.y, Input.GetTouch(1).position.x, Input.GetTouch(1).position.y, true) self.two_finger_drag_start_pos.change_state = 0 end self.two_finger_drag_start_pos.last_dist = self.two_finger_drag_start_pos.base_dist else self.two_finger_drag_start_pos = nil end ]] if Input.touchCount == 1 or Input.touchCount == 0 then x = ScreenToViewportPoint(x, 0) if x < 330 then self.touch_bengin_y = nil else self.touch_bengin_y = y end self.touch_bengin_x = x end end function Scene:OnDrag(x, y) --屏蔽视野操作 if true then return end -- if Input.touchCount == 2 and self.two_finger_drag_start_pos then -- local x0, y0 = Input.GetTouch(0).position.x, Input.GetTouch(0).position.y -- local x1, y1 = Input.GetTouch(1).position.x, Input.GetTouch(1).position.y -- local base_dist = self.two_finger_drag_start_pos.base_dist -- local now_dist = GameMath_GetDistance(x0, y0, x1, y1, true) -- local last_dist = self.two_finger_drag_start_pos.last_dist -- if (last_dist > now_dist and self.two_finger_drag_start_pos.change_state == 1) or (last_dist < now_dist and self.two_finger_drag_start_pos.change_state == 2) then -- self.two_finger_drag_start_pos.base_dist = last_dist -- base_dist = self.two_finger_drag_start_pos.base_dist -- end -- self.two_finger_drag_start_pos.last_dist = now_dist -- local off_y = ScreenToViewportPoint(now_dist - base_dist, 0) -- if off_y > 0 then -- off_y = off_y > 150 and 150 or off_y -- local new_size = self.main_camera.camera_curr_size * (1 - off_y / 1500) -- if new_size < 10 then -- new_size = 10 -- end -- self.main_camera:SetBaseCameraSize(new_size) -- self.two_finger_drag_start_pos.change_state = 1 -- else -- off_y = off_y < -150 and -150 or off_y -- local new_size = self.main_camera.camera_curr_size * (1 - off_y / 1500) -- if new_size > self.main_camera.camera_base_size * 1.3 then -- new_size = self.main_camera.camera_base_size * 1.3 -- end -- self.main_camera:SetBaseCameraSize(new_size) -- self.two_finger_drag_start_pos.change_state = 2 -- end -- return -- end if x < ScreenWidth/2 then return end if Input.touchCount == 1 or Input.touchCount == 0 then local mainrole = Scene.Instance:GetMainRole() if mainrole and mainrole.transform then local value = 0 if self.touch_bengin_x and math.abs(self.touch_bengin_x - x) > CameraRotateByScreen then if self.touch_bengin_x - x > CameraRotateByScreen then value = -1.5 elseif x - self.touch_bengin_x > CameraRotateByScreen then value = 1.5 end MainCamera.Instance:RotateAround(mainrole.transform.position,Vector3.up,value) self.touch_bengin_x = x end ------------------------- --Y轴上的视角变化 --[[ if self.touch_bengin_y and math.abs(self.touch_bengin_y - y) > CameraRotateByScreen then value = 0 if self.touch_bengin_y - y > CameraRotateByScreen then value = -1.5 elseif y - self.touch_bengin_y > CameraRotateByScreen then value = 1.5 end MainCamera.Instance:RotateAround(mainrole.transform.position, MainCamera.Instance.transform.right, value) MainCamera.Instance.isSmoothing = true MainCamera.Instance:SmoothPosToTarget() self.touch_bengin_y = y end --]] ------------------------- self.rotate_camera_state = true return end end if self.rotate_camera_state then self.rotate_camera_state = false self.wait_cancel_rotate_camera_state = true end end function Scene:OnTouchEnd(x,y) if self.two_finger_drag_start_pos then return end if not self.main_role then return end if self.main_role:IsFishingState() or self.main_role:IsInState(PoseState.TASK_JUMP) then --主角正在钓鱼 限制点击屏幕操作 return end if self.scene_mgr:IsPkBattleScene() and PkBattleModel:getInstance():IsTransferState() then Message.show("传送中,不能操作") return end if self.main_role then --无主角界面屏蔽点击操作 if self.main_role.disabled then return elseif self.touch_bengin_y then if self.touch_bengin_y - y > 100 then if self.last_change_horse_time and Time.time - self.last_change_horse_time < 2 then -- Message.show("操作过于频繁,请稍后") return end GlobalEventSystem:Fire(EventName.HIDE_HORSE) self.last_change_horse_time = Time.time return elseif y - self.touch_bengin_y > 100 then if self.last_change_horse_time and Time.time - self.last_change_horse_time < 2 then -- Message.show("操作过于频繁,请稍后") return end GlobalEventSystem:Fire(EventName.RIDE_HORSE) self.last_change_horse_time = Time.time return end end end if self.wait_cancel_rotate_camera_state then self.wait_cancel_rotate_camera_state = false return end local scene_pos = {} if self.mouse_down then local pos = Util.RaycastFromMouse(MainCamera.Instance.camera) if pos ~= Vector3.zero then scene_pos.x = pos.x * MainCamera.PixelsToUnits scene_pos.y = pos.z * MainCamera.PixelsToUnits else return end end --暂时先跑旧的拾取逻辑,后续优化 local query_list = self:PointQuery(scene_pos) local have_pick_info = (#query_list > 0) local clickTarget = query_list[1] or nil local is_pick_handled = true if clickTarget then if clickTarget:GetType() == SceneBaseType.Monster then --不能选中自己的怪 local is_mine = clickTarget:GetVo().role_id == RoleManager.Instance.mainRoleInfo.role_id if is_mine then return end ------------------------- --幻魔星域次数满了就不让点击选中了 local support_boss = GuildModel:getInstance():GetGuildSupportBossId( )--要过滤掉当前协助的进攻对象 if support_boss ~= clickTarget:GetVo().type_id then local is_desert_scene = self.scene_mgr:IsBossDesertedScene() or self.scene_mgr:IsDesertedBossCrossScene() if is_desert_scene then local monster_type = clickTarget:GetVo().boss_type if (monster_type == BossType.DesertedMonster) or (monster_type == BossType.DesertedBoss) then local rest_boss_time, rest_mon_time = BossModel:GetInstance():GetDesertedBossRestNum( ) if (rest_boss_time <= 0 and rest_mon_time > 0 and -- 仅有精英怪次数 打精英 monster_type == BossType.DesertedMonster) or (rest_boss_time > 0 and rest_mon_time <= 0 and -- 仅有BOSS次数 打BOSS monster_type == BossType.DesertedBoss) or (rest_boss_time > 0 and rest_mon_time > 0) -- 都有 then --对应次数还有,可以选中 else return end end end end ------------------------- if clickTarget:GetVo().type == MonsterType.COLLECT or clickTarget:GetVo().type == MonsterType.PICK or clickTarget:GetVo().type == MonsterType.TASK_COLLECT or clickTarget:GetVo().type == MonsterType.UD_COLLECT then if self.scene_mgr:IsGuildGuardDungeon() and not BaseDungeonModel:getInstance():IsCanCollect(clickTarget:GetVo().type_id) then Message.show("个人采集宝箱已达到上限") return end self:MainRoleAttackMonster(clickTarget) is_pick_handled = false elseif clickTarget:GetVo().type == MonsterType.PRICE and clickTarget:GetVo().can_attack ~= 1 then local npc_id = MonsterShowDialogWithNpcId[clickTarget:GetVo().type_id] if npc_id then GlobalEventSystem:Fire(SceneEventType.SHOW_TASK, npc_id) end else is_pick_handled = false end self.manual_target = clickTarget elseif clickTarget:GetType() == SceneBaseType.Role then if EscortModel:getInstance():IsEscortState() then--在护送屏蔽点击其他角色 return end if self:ForceAttackRole(clickTarget) then return end self:SetClickTarget(clickTarget,true) GlobalEventSystem:Fire(EventName.SHOW_OTHER_HEAD, true, clickTarget.vo, 1) return elseif clickTarget:GetType() == SceneBaseType.Npc then if clickTarget:IsClientNpc() or self.scene_mgr:IsClientHideNpc(clickTarget.id) then return end self:mainRoleToNpc(clickTarget.id) is_pick_handled = false self.manual_target = clickTarget elseif clickTarget:GetType() == SceneBaseType.Door then self:MainRoleMoveToDoor(clickTarget.vo) is_pick_handled = false self.manual_target = false return --直接return,不用SetClickTarget elseif clickTarget:GetType() == SceneBaseType.Build then local build_type = clickTarget:GetVo().id GlobalEventSystem:Fire(SceneEventType.ONCLICK_BUILD, clickTarget) is_pick_handled = false return end self:SetClickTarget(clickTarget) if (clickTarget:GetType() == SceneBaseType.Monster and clickTarget:GetVo().type == MonsterType.NORMAL and self.scene_mgr:IsCanAttackByMainRole(clickTarget:GetVo())) then EventSystem.Fire(GlobalEventSystem,EventName.STARTAUTOFIGHT, false, true) end Scene.Instance.user_manul_time = 0 end is_pick_handled = false if is_pick_handled then --嘲讽buff屏蔽点击移动 if self.main_role and self.main_role.buff_manager:hasChaofengBuff() then return end local idleMove = function() Scene.Instance.user_manul_time = Status.NowTime end if AutoFightManager:getInstance():GetAutoFightState() then local x = scene_pos.x local y = scene_pos.y AutoFightManager:getInstance():CacheGoToPos(x, y,self.scene_mgr:GetSceneId()) end --跳完后 不继续寻路 OperateManager.Instance.jump_end_not_continue = true local cache_x = scene_pos.x local cache_y = scene_pos.y if not scene_pos.x or not scene_pos.y then return end scene_pos.x = scene_pos.x/SceneObj_LogicRealRatio_x scene_pos.y = scene_pos.y/SceneObj_LogicRealRatio_y local is_endPos_block = self.scene_mgr:IsBlockXY(scene_pos.x, scene_pos.y) if is_endPos_block then self:MainRoleMove(scene_pos,0,idleMove) else self:MainRoleMove(scene_pos,0,idleMove) end self.user_manul_time = Status.NowTime --如果移动的时候选择目标是npc 则 取消 否则会影响挂机选择目标 if self.curr_click_target and self.curr_click_target:GetType() == SceneBaseType.Npc then self:CancelClickTarget() end self.find_monster_pos = false GlobalEventSystem:Fire(EventName.OPEN_LEFT_MIDDLE_MENU, false) --收起菜单 GlobalEventSystem:Fire(SceneEventType.TOUCH_GROUND_END) --点击场景,重置寻路状态 self:ResetUserManulState() end end --根据世界坐标选择被选中的模型 function Scene:PointQuery(world_pt, obj_type) local selected_list = {} local npc_obj_list = {} local query_list = nil obj_type = obj_type or SceneBaseType.All --全部 if obj_type == SceneBaseType.Npc or obj_type == SceneBaseType.All then for id,obj in pairs(self.npc_list) do if obj:CheckInBound(world_pt) then table_insert(npc_obj_list,obj) table_insert(selected_list,obj) end end end if obj_type == SceneBaseType.Role or obj_type == SceneBaseType.All then for id,obj in pairs(self.role_list) do if obj:CheckInBound(world_pt) and not obj.vo.is_virtual_friend then table_insert(selected_list,obj) end end end -- if obj_type == SceneBaseType.Partner or obj_type == SceneBaseType.All then -- for id,obj in pairs(self.partner_list) do -- if obj:CheckInBound(world_pt) then -- table_insert(selected_list,obj) -- end -- end -- end if obj_type == SceneBaseType.Monster or obj_type == SceneBaseType.All then for id,obj in pairs(self.monster_list) do if obj:CheckInBound(world_pt) then table_insert(selected_list,obj) end end end -- if obj_type == SceneBaseType.Other or obj_type == SceneBaseType.All then -- for id,obj in pairs(self.other_list) do -- if obj:CheckInBound(world_pt) then -- table_insert(selected_list,obj) -- end -- end -- end -- if obj_type == SceneBaseType.Door or obj_type == SceneBaseType.All then -- for id,obj in pairs(self.door_list) do -- if obj:CheckInBound(world_pt) then -- table_insert(selected_list,obj) -- end -- end -- end -- if obj_type == SceneBaseType.Build or obj_type == SceneBaseType.All then -- for id,obj in pairs(self.build_list) do -- if obj:CheckInBound(world_pt) then -- table_insert(selected_list,obj) -- end -- end -- end -- if obj_type == SceneBaseType.BuildBaby or obj_type == SceneBaseType.All then -- for id,obj in pairs(self.build_baby_list) do -- if obj:CheckInBound(world_pt) then -- table_insert(selected_list,obj) -- end -- end -- end if #npc_obj_list > 0 then if #npc_obj_list > 1 then local function onSortHandler(v1,v2) return v1.real_pos.y < v2.real_pos.y end table_sort(npc_obj_list,onSortHandler) end return npc_obj_list end if #selected_list > 1 then --根据y轴方向排序 y越小越靠前 local function onSortHandler(v1,v2) return v1.real_pos.y < v2.real_pos.y end table_sort(selected_list,onSortHandler) end return selected_list end --手动选中目标,强制切换到战斗 function Scene:ForceAttackRole(clickTarget) if clickTarget and self.scene_mgr:IsCanAttackByMainRole(clickTarget:GetVo(), true) then self:SetClickTarget(clickTarget) self:MainRoleAttackRole(clickTarget) GlobalEventSystem:Fire(EventName.STARTAUTOFIGHT) self.scene_mgr:SetAttackHeadVo(clickTarget.vo, nil, true) return true end return false end function Scene:MainRoleMoveToDoor(door_vo) local dx, dy = door_vo.pixel_x/SceneObj_LogicRealRatio_x, door_vo.pixel_y/SceneObj_LogicRealRatio_y local lx, ly = self.main_role:GetLogicPos() if GameMath_GetDistance(lx, ly, dx, dy, false) <= 1 then self:RoleWalkCompleteHandler() else self:MainRoleMove(co.TableXY(dx, dy)) end end function Scene:mainRoleToNpc(npc_id) local npc_info = self.scene_mgr:GetNpcVo(npc_id) if npc_info == nil then return end local npcpos = co.TableXY(npc_info.logic_x, npc_info.logic_y) local rolepos = co.TableXY(self.main_role:GetLogicPos()) local dist = 2--ActionDis.NPC local check_distance = 420 if self.main_role and self.main_role:IsOnHorse() then dist = 2.5 check_distance = 500 end local action_func = function () if not self.main_role then return end -- 转向 self:clearGoToData() if self.main_role:IsInState(PoseState.MOVE) then self.main_role:DoStand() end local dir2 = co.SubtractXYTable(npcpos, rolepos) self.main_role:SetDirection(dir2) -- local is_fire_evt = OperateManager.Instance:StopMove() local npc = self:GetNpc(npc_id) if npc ~= nil then self:SetClickTarget(npc) if npc.vo and not Config.ConfigGuildWar.KeepDirectNpc[npc.vo.type_id] then local dir = co.TableXY(self.main_role.real_pos.x - npc.real_pos.x, self.main_role.real_pos.y - npc.real_pos.y) npc:SetDirection(dir) end if GameMath_GetDistance(self.main_role.real_pos.x, self.main_role.real_pos.y, npc.real_pos.x, npc.real_pos.y, true) < check_distance then -- if FishModel:getInstance():IsFishNpc(npc_id) then --如果是钓鱼NPC 就打开钓鱼对话界面 -- GlobalEventSystem:Fire(EventName.OPEN_FISH_NPC_VIEW,npc_info,true) -- else GlobalEventSystem:Fire(SceneEventType.SHOW_TASK, npc_info.instance_id) -- end end end -- if not is_fire_evt then GlobalEventSystem:Fire(EventName.FINDWAY_ENDED) -- end end local npc = self:GetNpc(npc_id) if npc ~= nil then self:SetClickTarget(npc) end -- 如果已经在范围内了 if GameMath_GetDistance(npcpos.x, npcpos.y, rolepos.x, rolepos.y, true) <= dist + 1 then action_func() else self:MainRoleMoveAndCancel(co.TableXY(npc_info.logic_x, npc_info.logic_y), dist, action_func,false) end end --[[ * 移动并取消攻击对象等 * @param point 目标点 * ]] function Scene:MainRoleMoveAndCancel(point, range, end_function,is_fire_evt) if self:ChcekCanMove() == false then return end range = range or 0 --定点移动 self:MainRoleMove(point, range, end_function,is_fire_evt) if SkillManager.getInstance().currentSkillId ~= 0 then SkillManager.getInstance():setCurrentSkillId() end end --[[ *获得该点下的出口 * @param point * @return * ]] function Scene:GetExitByPoint(posX, posY,dist,enter_scene_id) dist = dist or 2 enter_scene_id = enter_scene_id or 0 for i,door in pairs(self.door_list) do local door_posX, door_posY = door:GetLogicPos() if GameMath.IsPointNear(posX, posY, door_posX, door_posY, dist) and (enter_scene_id == 0 or door.id == enter_scene_id) then return door end end return nil; end function Scene:GetExitByJump(posX, posY) for i,jumppoint in pairs(self.jumppoint_list) do local jump_posX, jump_posY = jumppoint:GetLogicPos() if GameMath.IsPointNear(posX, posY, jump_posX, jump_posY, 2) then return jumppoint end end return nil; end --[[ 功能:主角走完后处理事件 其他. 作者:zsm ]] function Scene:RoleWalkCompleteHandler(not_fire_move_end) if self.is_clearing then --正在清理场景或者主角被锁定动作状态不能处理走完动作 return end local main_role = self:GetMainRole() if main_role:IsInState(PoseState.ATTACK) or main_role:IsGhostMode() then return end if main_role.is_shoe_flying then return end self:clearGoToData() if not not_fire_move_end then GlobalEventSystem:Fire(SceneEventType.MAIN_ROLE_MOVE_END) end --场景加载完后加个cd限制,避免出生在传送阵附近又马上被传送走(前提是切换场景只会走一次传送门) if self.scene_load_view_complete_time and Time.time - self.scene_load_view_complete_time < 3 then return end --传送点 local door = self:GetExitByPoint(self.main_role:GetLogicPos()) local now_oper = OperateManager.Instance:GetNowSrcOper() -- if door ~= nil and (door:GetVo().is_same_scene or now_oper == nil or (now_oper.now_use_pair == nil and now_oper.total_pair == nil ) -- or (now_oper.now_use_pair and now_oper.total_pair and now_oper.now_use_pair > now_oper.total_pair)) then if door ~= nil and (not now_oper or (not now_oper.now_use_pair and not now_oper.total_pair) or (now_oper.now_use_pair and now_oper.total_pair and now_oper.now_use_pair > now_oper.total_pair)) then local scene_info = ConfigItemMgr.Instance:GetSceneItem(door:GetVo().enter_scene_id) local function scene_door_callback() local temp_scene_id = door:GetVo().enter_scene_id local temp_send_type = SceneTransType.GateNear local temp_x, temp_y = 0, 0 local task_send_type, task_find_vo = TaskModel:getInstance():GetChangeSceneType() if task_send_type and task_find_vo then temp_send_type = task_send_type temp_scene_id = task_find_vo.sceneId temp_x, temp_y = task_find_vo.x*SceneObj_LogicRealRatio_x, task_find_vo.y*SceneObj_LogicRealRatio_y end local data = { scene_id = temp_scene_id, send_type = temp_send_type, x = temp_x, y = temp_y, } --print("tanar: [Scene 2562]=> door:GetVo().x, door:GetVo().y: ",door:GetVo().x, door:GetVo().y) SceneController.Instance:ClientRequestChangeScene(-1,data) self.change_scene_request_time = Status.NowTime TaskModel:getInstance():SetChangeSceneType(false) end if self.change_scene_request_time == nil then scene_door_callback() elseif Status.NowTime - self.change_scene_request_time > 1.5 then scene_door_callback() end end -- self:CheckMainUICollectBtnState() end --设置下面那个函数的限定ID列表 function Scene:SetCheckCollectBtnLimitIdList(list,all) self.check_collect_btn_limit_list = list self.check_collect_btn_all = all end --检测主界面采集按钮显示状态 function Scene:CheckMainUICollectBtnState() if not(SceneManager:getInstance():IsMainCityAndFieldScene() or SceneManager:getInstance():IsTeamDungeonScene() or SceneManager:getInstance():IsGuildGuardDungeon()) then return end local vo = nil local x1, y1 = self.mainrole_vo.pos_x, self.mainrole_vo.pos_y local x2, y2 = nil local show_collect_btn = false local collect_vo = nil for v, monster in pairs(self.monster_list) do local vo = monster:GetVo() if self.check_collect_btn_all or (self.check_collect_btn_limit_list and self.check_collect_btn_limit_list[vo.type_id]) then if vo and (vo.type == MonsterType.COLLECT or vo.type == MonsterType.TASK_COLLECT or vo.type == MonsterType.MISSION_COLLECT or vo.type == MonsterType.UD_COLLECT) then x2, y2 = monster:GetRealPos() local dis = GameMath_GetDistance(x1, y1, x2, y2, false) if dis<= 150000 then show_collect_btn = true collect_vo = v break end end end end GlobalEventSystem:Fire(EventName.SHOW_MAINUI_COLLECT_BTN, show_collect_btn,collect_vo) end function Scene:ChcekCanMove() if self.mainrole_vo.chaosTime > 0 then Message.show("你处于混乱状态,暂时不能自由移动!") return false end return true end function Scene:CreateDoor(door_vo) local id = door_vo.enter_scene_id if door_vo.is_same_scene then id = door_vo.enter_scene_id.."-"..door_vo.index end local obj = { id = id, type = SapManager.ObjType.Door, pos = co.TableXY(door_vo.pixel_x,door_vo.pixel_y), size = co.TableXY(100,100), data = door_vo, } SapManager:getInstance():RegisterObj(obj) end function Scene:CreateJumpPoint(jumppoint_vo) local obj = { id = jumppoint_vo.instance_id, type = SapManager.ObjType.JumpPoint, pos = co.TableXY(jumppoint_vo.real_pos.x,jumppoint_vo.real_pos.y), size = co.TableXY(100,100), data = jumppoint_vo, } SapManager:getInstance():RegisterObj(obj) end function Scene:CreateWayPoint(waypoint_vo) if self.waypoint == nil then self.waypoint = WayPoint.New(waypoint_vo) end if self.waypoint then self.waypoint:InitWayPointVo(waypoint_vo) end return self.waypoint, true end --is_same_scene 是否场景 function Scene:CreateMainRole() local main_role = MainRole.New(self.mainrole_vo) print("CreateMainRole 主角坐标:", main_role.vo.pos_x, main_role.vo.pos_y, Status.NowTime) local id = main_role.id self.role_list[id] = main_role self:SetMainRole(main_role) main_role:LoadInfoFromVo() GlobalEventSystem:Fire(EventName.CREATE_MAIN_ROLE_SUCCESS) GlobalEventSystem:Fire(EventName.SHOWRELIVEWINDOW,1) --关闭复活界面 self.mapView:ResetSceneActionObjHeight() SkillManager:getInstance().joy_stick_dir = nil return main_role, true end function Scene:CreateRole(role_vo) if not self.main_role then return end local role_id = role_vo.role_id if role_id == RoleManager.Instance:GetMainRoleId() then self.mainrole_vo:ChangeFromVo(role_vo) return end -- 角色复活 local exist_role = self.role_list[role_id] if exist_role then GlobalEventSystem:Fire(EventName.EXECUTE_DELEY_FIGHT_INFO) self:DeleteRole(role_id) end local role = self.role_pool:GetObjFreeList() if role == nil then role = Role.New() end self.role_list[role_id] = role role:InitRoleVo(role_vo) role:LoadInfoFromVo() return role, true end function Scene:CreateHookRole(role_vo) local role_id = role_vo.role_id local exist_role = self.hook_role_list[role_id] if exist_role then GlobalEventSystem:Fire(EventName.EXECUTE_DELEY_FIGHT_INFO) self:DeleteHookRole(role_id) end local role = self.hook_role_pool:GetObjFreeList() if role == nil then role = HookRole.New() end self.hook_role_list[role_id] = role role:InitRoleVo(role_vo) role:LoadInfoFromVo() return role, true end function Scene:CreatePartner(partner_vo) if not self.main_role then return end local partner_id = partner_vo.partner_id local exist_partner = self.partner_list[partner_id] if exist_partner then GlobalEventSystem:Fire(EventName.EXECUTE_DELEY_FIGHT_INFO) self:DeletePartner(partner_id) end local partner = self.partner_pool:GetObjFreeList() if partner == nil then partner = Partner.New() end self.partner_list[partner_id] = partner partner:InitPartnerVo(partner_vo) partner:LoadInfoFromVo() if lua_viewM.is_lock_screen then partner:SetModelHideFlag(SceneObj.ModelHideFlag.IndependentHide2, true) end return partner, true end function Scene:CreateNpc(npc_vo) local npc_exist = self.npc_list[tonumber(npc_vo.instance_id)] if npc_exist == nil then -- 见到才加载模式 local obj = { id = npc_vo.instance_id, type = SapManager.ObjType.NPC, pos = co.TableXY(npc_vo.pos_x,npc_vo.pos_y), size = co.TableXY(100,100), data = npc_vo, } SapManager:getInstance():RegisterObj(obj) else npc_exist.vo = npc_vo npc_exist:SetCfgActionAndAngle() npc_exist:BindVoEvents() npc_exist:DoMove(co.TableXY(npc_vo.pos_x, npc_vo.pos_y)) npc_exist.move_flag = MOVE_TYPE.NORMOL_MOVE end end function Scene:CreateMonster(monster_vo) local monster = self.monster_list[monster_vo.instance_id] if monster ~= nil then self.monster_pool:ReleaseObj(monster) self.monster_list[monster_vo.instance_id] = nil end monster = self.monster_pool:GetObjFreeList() if monster == nil then monster = Monster.New() end self.monster_list[monster_vo.instance_id] = monster monster:InitMonsterVo(monster_vo) monster:LoadInfoFromVo() if (self.is_hide_all_mon or monster:HasBlockSetting("monster")) and not self.scene_mgr:IsNotBlockMonsterScene() then monster:SetModelHideFlag(SceneObj.ModelHideFlag.RoleNumLimit, true) end return monster, true end function Scene:CreateOther(other_vo) local other = self.other_list[other_vo.instance_id] if other ~= nil then self.other_pool:ReleaseObj(other) self.other_list[other_vo.instance_id] = nil end other = self.other_pool:GetObjFreeList() if other == nil then other = Other.New() end self.other_list[other_vo.instance_id] = other other:InitOtherVo(other_vo) other:LoadInfoFromVo() return other, true end function Scene:CreateSprite(owner, owner_vo) local sprite = self.sprite_list[owner.id] if sprite ~= nil then self.sprite_pool:ReleaseObj(sprite) self.sprite_list[owner.id] = nil end sprite = self.sprite_pool:GetObjFreeList() if sprite == nil then sprite = Sprite.New() end self.sprite_list[owner.id] = sprite local sprite_vo = SpriteVo.New() sprite_vo:SetVo(owner:GetVo()) sprite:InitSpriteVo(owner, sprite_vo) sprite:LoadInfoFromVo() return sprite, true end function Scene:DeleteSprite(instance_id ) local sprite = self.sprite_list[instance_id] if sprite ~= nil then self.sprite_list[instance_id] = nil self.sprite_pool:ReleaseObj(sprite) end end ---------守护------ function Scene:CreateEvil(owner, owner_vo) local evil = self.evil_list[owner.id] if evil ~= nil then self.evil_pool:ReleaseObj(evil) self.evil_list[owner.id] = nil end evil = self.evil_pool:GetObjFreeList()--自由动作列表 if evil == nil then evil = Evil.New() end self.evil_list[owner.id] = evil local evil_vo = EvilVo.New() evil_vo:SetVo(owner:GetVo()) evil:InitEvilVo(owner, evil_vo) evil:LoadInfoFromVo() return evil, true end function Scene:DeleteEvil(instance_id ) local sprite = self.evil_list[instance_id] if sprite ~= nil then self.evil_list[instance_id] = nil self.evil_pool:ReleaseObj(sprite) end end ---------------------------------- 宠物相关 ---------------- function Scene:CreatePokemon(owner,owner_vo) local pokemon = self.pokemon_list[owner.id] if pokemon ~= nil then self.pokemon_pool:ReleaseObj(pokemon) self.pokemon_list[owner.id] = nil end pokemon = self.pokemon_pool:GetObjFreeList() if pokemon == nil then pokemon = Pokemon.New() end self.pokemon_list[owner.id] = pokemon local pokemon_vo = PokemonVo.New() pokemon_vo:SetVo(owner.id, owner_vo.pokemon_id, owner_vo.pokemon_star) pokemon:InitPokemonVo(owner, owner_vo, pokemon_vo) pokemon:LoadInfoFromVo() return pokemon, true end function Scene:DeletePokemon(instance_id ) local pokemon = self.pokemon_list[instance_id] if pokemon ~= nil then self.pokemon_list[instance_id] = nil self.pokemon_pool:ReleaseObj(pokemon) end end ---------------------------------- 宠物副本协战宠物相关 ---------------- function Scene:CreateAssisitPokemon(owner,owner_vo,assisit_pokemon_id,index) local assisit_pokemon = nil if self.assisit_pokemon_list[owner.id] and self.assisit_pokemon_list[owner.id][index] then assisit_pokemon = self.assisit_pokemon_list[owner.id][index] end if assisit_pokemon ~= nil then self.assisit_pokemon_pool:ReleaseObj(assisit_pokemon) self.assisit_pokemon_list[owner.id][index] = nil end assisit_pokemon = self.assisit_pokemon_pool:GetObjFreeList() if assisit_pokemon == nil then assisit_pokemon = AssisitPokemon.New() end self.assisit_pokemon_list[owner.id] = self.assisit_pokemon_list[owner.id] or {} self.assisit_pokemon_list[owner.id][index] = assisit_pokemon local assisit_pokemon_vo = AssisitPokemonVo.New() local assisit_pokemon_data = PetModel:getInstance():GetPetListById(assisit_pokemon_id) local assisit_pokemon_star = 1 if assisit_pokemon_data then assisit_pokemon_star = assisit_pokemon_data.pet_star end assisit_pokemon_vo:SetVo(owner.id, assisit_pokemon_id, assisit_pokemon_star,index) assisit_pokemon:InitPokemonVo(owner, owner_vo, assisit_pokemon_vo) assisit_pokemon:LoadInfoFromVo() return assisit_pokemon, true end function Scene:DeleteAssisitPokemon(instance_id ,index) local assisit_pokemon = nil if self.assisit_pokemon_list[instance_id] and self.assisit_pokemon_list[instance_id][index] then assisit_pokemon = self.assisit_pokemon_list[instance_id][index] end if assisit_pokemon ~= nil then self.assisit_pokemon_list[instance_id][index] = nil self.assisit_pokemon_pool:ReleaseObj(assisit_pokemon) end end ---------------------------------- ai娘相关 ---------------- function Scene:CreatePet(owner,owner_vo) local pet = self.pet_list[owner.id] if pet ~= nil then self.pet_pool:ReleaseObj(pet) self.pet_list[owner.id] = nil end pet = self.pet_pool:GetObjFreeList() if pet == nil then pet = Pet.New() end self.pet_list[owner.id] = pet local pet_vo = PetVo.New() pet_vo:SetVo(owner.id, owner_vo.pet_id) pet:InitPetVo(owner, owner_vo, pet_vo) pet:LoadInfoFromVo() return pet, true end function Scene:DeletePet(instance_id ) local pet = self.pet_list[instance_id] if pet ~= nil then self.pet_list[instance_id] = nil self.pet_pool:ReleaseObj(pet) end end ---------------------------------- 宝宝相关 ---------------- function Scene:CreateBaby(owner,owner_vo) local baby = self.baby_list[owner.id] if baby ~= nil then self.baby_pool:ReleaseObj(baby) self.baby_list[owner.id] = nil end baby = self.baby_pool:GetObjFreeList() if baby == nil then baby = Baby.New() end self.baby_list[owner.id] = baby local baby_vo = BabyVo.New() baby_vo:SetVo(owner.id, owner_vo,owner_vo.baby_id) baby:InitBabyVo(owner, owner_vo, baby_vo) baby:LoadInfoFromVo() return baby, true end function Scene:DeleteBaby(instance_id) local baby = self.baby_list[instance_id] if baby ~= nil then self.baby_list[instance_id] = nil self.baby_pool:ReleaseObj(baby) end end ----------------------本服团战粮草护送相关--------------- function Scene:CreateGWFollower(owner) local gwfollower = self.gwfollower_list[owner.id] if gwfollower ~= nil then self.gwfollower_pool:ReleaseObj(gwfollower) self.gwfollower_list[owner.id] = nil end gwfollower = self.gwfollower_pool:GetObjFreeList() if gwfollower == nil then gwfollower = GWFollower.New() end self.gwfollower_list[owner.id] = gwfollower local gwfollower_vo = GWFollowerVo.New() gwfollower_vo:SetVo(owner:GetVo()) gwfollower:InitGWFollowerVo(owner, gwfollower_vo) gwfollower:LoadInfoFromVo() return gwfollower, true end function Scene:DeleteGWFollower(instance_id ) local gwfollower = self.gwfollower_list[instance_id] if gwfollower ~= nil then self.gwfollower_list[instance_id] = nil self.gwfollower_pool:ReleaseObj(gwfollower) end end ------------------------------------------------------------------ ----------------------跳一跳跳台相关--------------- function Scene:CreateJumpOneStep(vo, step_id) local jump_one_step = self.jump_one_step_list[step_id] if jump_one_step ~= nil then self.jump_one_step_pool:ReleaseObj(jump_one_step) self.jump_one_step_pool[step_id] = nil end jump_one_step = self.jump_one_step_pool:GetObjFreeList() if jump_one_step == nil then jump_one_step = JumpOneStep.New() end self.jump_one_step_list[step_id] = jump_one_step jump_one_step:InitStepVo(vo) return jump_one_step, true end function Scene:DeleteJumpOneStep(step_id ) local jump_one_step = self.jump_one_step_list[step_id] if jump_one_step ~= nil then self.jump_one_step_list[step_id] = nil self.jump_one_step_pool:ReleaseObj(jump_one_step) end end ------------------------------------------------------------------ -------------家园建筑宝宝相关 function Scene:CreateBuildBaby(build_baby_vo) local buildBaby = self.build_baby_list[build_baby_vo.instance_id] if buildBaby == nil then buildBaby = BuildBaby.New() self.build_baby_list[build_baby_vo.instance_id] = buildBaby buildBaby:InitBuildtBabyVo(build_baby_vo) buildBaby:LoadInfoFromVo() end return buildBaby,true end function Scene:DeleteBuildBaby( build_baby_id ) local buildBaby = self.build_baby_list[build_baby_id] if buildBaby ~= nil then self.build_baby_list[build_baby_id]:DeleteMe() self.build_baby_list[build_baby_id] = nil end end ----------------------家园相关--------------- function Scene:CreateBuild(build_vo) local build = self.build_list[build_vo.instance_id] if build == nil then build = Build.New() self.build_list[build_vo.instance_id] = build end build:InitBuildtVo(build_vo) build:LoadInfoFromVo() return build, true end function Scene:DeleteBuild( build_id ) local build = self.build_list[build_id] if build ~= nil then self.build_list[build_id]:DeleteMe() self.build_list[build_id] = nil end end function Scene:CreateFurniture(furniture_vo) local furniture = self.furniture_list[furniture_vo.instance_id] if furniture == nil then furniture = Furniture.New() self.furniture_list[furniture_vo.instance_id] = furniture end furniture:InitFurnituretVo(furniture_vo) furniture:LoadInfoFromVo() return furniture, true end function Scene:DeleteFurniture( furniture_id ) local furniture = self.furniture_list[furniture_id] if furniture ~= nil then self.furniture_list[furniture_id]:DeleteMe() self.furniture_list[furniture_id] = nil end end ------------------------------------------------------------------ function Scene:CreateDropObj(drop_vo,center_x,center_y) local drop = self.drop_list[drop_vo.drop_id] if drop ~= nil then self.drop_pool:ReleaseObj(drop) self.drop_list[drop_vo.drop_id] = nil end drop = self.drop_pool:GetObjFreeList() if drop == nil then drop = SceneDropObj.New() end drop:InitDropVo(drop_vo,center_x,center_y) self.drop_list[drop_vo.drop_id] = drop GlobalEventSystem:DelayFire(EventName.EVIL_AUTO_PICK) return drop, true end --删除某个人的掉落当他离开场景 function Scene:DeleteDropWhenLeaveScene(role_id) for k,drop in pairs(self.drop_list) do local vo = drop:GetDropVo() if vo and vo.role_id == role_id then --如果是自己的先显示提示 if vo.role_id == RoleManager.Instance:GetMainRoleId() then drop:ShowDropTip() end self:DeleteDropObj(vo.drop_id) end end end function Scene:DeleteRole( role_id ) local obj = self.role_list[role_id] if obj ~= nil then if obj == self.main_role then print("warning:try to remove mainrole as normal role , failed!") return end --删除该对象的闭包函数 local del_role_func = function ( ) self.role_list[role_id] = nil self.role_pool:ReleaseObj(obj) end if self.is_in_update then --更新过程中延时删除 table_insert(self.delay_handle_funcs, del_role_func) else --直接删除对象 del_role_func() end if obj == self.curr_click_target then self:CancelClickTarget(true) end end end --删除离线挂机角色 function Scene:DeleteHookRole(role_id) local obj = self.hook_role_list[role_id] if obj then self.hook_role_pool:ReleaseObj(obj) self.hook_role_list[role_id] = nil end end function Scene:DeletePartner( partner_id ) local obj = self.partner_list[partner_id] if obj ~= nil then local del_partner_func = function ( ) self.partner_list[partner_id] = nil self.partner_pool:ReleaseObj(obj) end if self.is_in_update then --更新过程中延时删除 table_insert(self.delay_handle_funcs, del_partner_func) else --直接删除对象 del_partner_func() end end end function Scene:GetMonsterDeadBody(instance_id) for _, monster in pairs(self.dead_body_list) do if monster.id == instance_id then return monster end end return nil end function Scene:DeleteMonster( instance_id ) local monster = self.monster_list[instance_id] if monster ~= nil then self.monster_list[instance_id] = nil --把怪物尸体放到另一个队列里 self.dead_body_count = self.dead_body_count + 1 self.dead_body_list[self.dead_body_count] = monster monster:SetDeadBodyID(self.dead_body_count) --如果不是死亡时的删除,要让怪物Fade渐隐 if not monster:IsDead() then local dead_body_id = self.dead_body_count self:DeleteDeadBody(dead_body_id) end if monster == self.curr_click_target then self:CancelClickTarget() end end end function Scene:DeleteOther( instance_id ) local other = self.other_list[instance_id] if other ~= nil then self.other_list[instance_id] = nil self.other_pool:ReleaseObj(other) end end --删除怪物尸体 function Scene:DeleteDeadBody(dead_body_id) local obj = self.dead_body_list[dead_body_id] if obj then self.monster_pool:ReleaseObj(obj) self.dead_body_list[dead_body_id] = nil end end function Scene:DeleteDoor( enter_scene_id ) SapManager:getInstance():UnRegisterObj(SapManager.ObjType.Door,enter_scene_id) end function Scene:DeleteJumpPoint( id ) SapManager:getInstance():UnRegisterObj(SapManager.ObjType.JumpPoint,id) end function Scene:DeleteNpc( ins_id ) SapManager:getInstance():UnRegisterObj(SapManager.ObjType.NPC,ins_id) end function Scene:DeleteDropObj( drop_id ) local drop = self.drop_list[drop_id] if drop ~= nil then self.drop_pool:ReleaseObj(drop) self.drop_list[drop_id] = nil end end function Scene:DeleteWayPoint( id ) if self.waypoint ~= nil then self.waypoint:DeleteMe() self.waypoint = nil end end function Scene:clearGoToData() self.goToPos = nil self.goToFunc = nil end function Scene:ClearScene(clear_doors_npcs_jumps) if clear_doors_npcs_jumps == nil then clear_doors_npcs_jumps = true end if clear_doors_npcs_jumps then self.is_clearing = true end --先清空所有对象列表 再执行DeleteMe 避免执行DeleteMe操作的过程中调用列表 导致vo为nil local role_delete_list_proxy = self.role_list self.role_list = {} local partner_delete_list_proxy = self.partner_list self.partner_list = {} local monster_delete_list_proxy = self.monster_list self.monster_list = {} local dead_body_delete_list_proxy = self.dead_body_list self.dead_body_list = {} local other_delete_list_proxy = self.other_list self.other_list = {} local drop_delete_list_proxy = self.drop_list self.drop_list = {} local sprite_delete_list_proxy = self.sprite_list self.sprite_list = {} local evil_delete_list_proxy = self.evil_list self.evil_list = {} local pet_delete_list_proxy = self.pet_list self.pet_list = {} local pokemon_delete_list_proxy = self.pokemon_list self.pokemon_list = {} local assisit_pokemon_delete_list_proxy = self.assisit_pokemon_list self.assisit_pokemon_list = {} local baby_delete_list_proxy = self.baby_list self.baby_list = {} local gwflollower_delete_list_proxy = self.gwfollower_list self.gwfollower_list = {} local grave_delete_list_proxy = self.grave_list self.grave_list = {} local hook_role_delete_list_proxy = self.hook_role_list self.hook_role_list = {} local build_delete_list_proxy = self.build_list self.build_list = {} local jump_one_step_delete_list_proxy = self.jump_one_step_list self.jump_one_step_list = {} local furniture_delete_list_proxy = self.furniture_list self.furniture_list = {} -- local build_baby_delete_list_proxy = self.build_baby_list -- for _,v in ipairs(build_baby_delete_list_proxy) do -- v:DeleteMe() -- end -- self.build_baby_list = {} for _, v in pairs(build_delete_list_proxy) do v:DeleteMe() end for _, v in pairs(furniture_delete_list_proxy) do v:DeleteMe() end for _, v in pairs(role_delete_list_proxy) do if self.main_role ~= v then self.role_pool:ReleaseObj(v) end end for _, v in pairs(partner_delete_list_proxy) do self.role_pool:ReleaseObj(v) end for _, v in pairs(monster_delete_list_proxy) do self.monster_pool:ReleaseObj(v) end for _, v in pairs(dead_body_delete_list_proxy) do self.monster_pool:ReleaseObj(v) end for _, v in pairs(other_delete_list_proxy) do self.other_pool:ReleaseObj(v) end for _, v in pairs(drop_delete_list_proxy) do self.drop_pool:ReleaseObj(v) end for _, v in pairs(sprite_delete_list_proxy) do self.sprite_pool:ReleaseObj(v) end for _, v in pairs(evil_delete_list_proxy) do self.evil_pool:ReleaseObj(v) end for _, v in pairs(pet_delete_list_proxy) do self.pet_pool:ReleaseObj(v) end for _, v in pairs(pokemon_delete_list_proxy) do self.pokemon_pool:ReleaseObj(v) end for _, list in pairs(assisit_pokemon_delete_list_proxy) do for _, v in pairs(list) do self.assisit_pokemon_pool:ReleaseObj(v) end end for _, v in pairs(baby_delete_list_proxy) do self.baby_pool:ReleaseObj(v) end for _, v in pairs(gwflollower_delete_list_proxy) do self.gwfollower_pool:ReleaseObj(v) end for _, v in pairs(jump_one_step_delete_list_proxy) do self.jump_one_step_pool:ReleaseObj(v) end for _, v in pairs(grave_delete_list_proxy) do self.grave_pool:ReleaseObj(v) end for _, v in pairs(hook_role_delete_list_proxy) do self.hook_role_pool:ReleaseObj(v) end self:clearGoToData() if clear_doors_npcs_jumps then for _, v in pairs(self.npc_list) do self.npc_pool:ReleaseObj(v) end self.npc_list = {} for _, v in pairs(self.door_list) do v:DeleteMe() end self.door_list = {} for _, v in pairs(self.jumppoint_list) do v:DeleteMe() end self.jumppoint_list = {} end if self.waypoint then self.waypoint:DeleteMe() self.waypoint = nil end LuaViewManager:getInstance():ClearTimer() --清除所有粒子特效 ParticleManager:getInstance():DelAllEffects(clear_doors_npcs_jumps) --主角最后删除 if self.main_role then self.main_role:DeleteMe() self.main_role = nil end self.enable_click_screen = true self.curr_click_target = false self.manual_target = false self.find_monster_pos = false if self.click_target_effect then destroy(self.click_target_effect) self.effect_res = nil self.click_target_effect = nil self.recreate_target_effect = false end -- OperateManager.Instance:ClearAllPokemonSrcOper() end function Scene:UnBindMainRoleVo() if self.main_role then self.main_role:UnBindVo() end end function Scene:MainRoleMove(end_pos, range, end_function,is_fire_evt) self:clearGoToData() local orign_end_pos = Vector2(end_pos.x, end_pos.y) --一开始传进来的结束坐标,用来跳跃后重新计算路径 range = range or 0 if range > 0 then local start_pos = Vector2(self.main_role:GetLogicPos()) local path_info = self.mapView:FindWay(start_pos, Vector2(end_pos.x, end_pos.y), range) if path_info then local total_point = #path_info if total_point >= 1 then local game_end_pos = path_info[total_point] end_pos.x, end_pos.y = game_end_pos.x, game_end_pos.y end end end self.goToPos = end_pos self.goToFunc = end_function is_fire_evt = is_fire_evt == nil and true or is_fire_evt local function end_func() self:clearGoToData() if is_fire_evt then GlobalEventSystem:Fire(EventName.FINDWAY_ENDED) end if end_function ~= nil then end_function() end end OperateManager.Instance:StartMoveAction(end_pos, end_func, orign_end_pos, range) end function Scene:GetRole(role_id) if role_id == RoleManager.Instance:GetMainRoleId() then return self:GetMainRole() end return self.role_list[role_id] end function Scene:GetAllRole() return self.role_list end --rx,ry玩家真实坐标 --flag 玩家移动方式 -- args_1, args_2, args_3, args_4 移动自定义参数 function Scene:RoleMove(role_id, rx, ry, flag, args_1, args_2, args_3, args_4) flag = flag or 0 x = rx or 0 y = ry or 0 local role = self:GetRole(role_id) if role ~= nil then role.move_flag = flag local end_pos = co.TempVector2(x, y) if flag == MOVE_TYPE.NORMOL_MOVE then --正常移动 if not role:IsInState(PoseState.JUMP) then role:FindPathAndMove(end_pos) end elseif flag == MOVE_TYPE.JUMP then -- 跳跃 role:DoJumpFromRoleMove(args_1, args_2, args_3, args_4, Role.MULTI_JUMP_TYPE.Jump_1) elseif flag == MOVE_TYPE.ACCELERATE then --加速 role:FindPathAndMove(end_pos) elseif flag == MOVE_TYPE.FLASH then --闪现闪避 local dir = co.TableXY(end_pos.x - role.real_pos.x, end_pos.y - role.real_pos.y) role:SetDirection(dir) role:DoFlash(end_pos) elseif flag == MOVE_TYPE.RUSH then --冲刺 role:DoRush(end_pos) elseif flag == MOVE_TYPE.BLINK then --瞬移 role:SetRealPos(x,y) role:DoStand() elseif flag == MOVE_TYPE.TASK_JUMP then --任务三段跳 role:DoJumpFromRoleMove(args_1, args_2, args_3, args_4, Role.MULTI_JUMP_TYPE.Jump_2) else end role:GetVo().pos_x = end_pos.x role:GetVo().pos_y = end_pos.y end_pos:DeleteV() else -- print("warning! can not find a role to handle move response!") end end function Scene:MonsterMove(instance_id, pos_x, pos_y, speedFlag, endDirState) speedFlag = speedFlag or 0 local monster = self:GetMonster(instance_id) if monster ~= nil then if self.monster_move_end_pos == nil then self.monster_move_end_pos = {x = pos_x, y = pos_y} else self.monster_move_end_pos.x, self.monster_move_end_pos.y = pos_x, pos_y end if lua_viewM.is_lock_screen then monster:SetRealPos(self.monster_move_end_pos.x,self.monster_move_end_pos.y) else -- monster:SetMoveEndPos(pos_x,pos_y) monster:FindPathAndMove(self.monster_move_end_pos) end end end function Scene:PartnerMove(instance_id, pos_x, pos_y, speedFlag, endDirState) speedFlag = speedFlag or 0 local partner = self:GetPartner(instance_id) if partner ~= nil then local end_pos = co.TableXY(pos_x, pos_y) partner:FindPathAndMove(end_pos) end end function Scene:OtherMove(instance_id, pos_x, pos_y, speedFlag, endDirState) speedFlag = speedFlag or 0 local other = self:GetOther(instance_id) if other ~= nil then local end_pos = co.TableXY(pos_x, pos_y) other:FindPathAndMove(end_pos) end end function Scene:NpcMove(instance_id, pos_x, pos_y, dir, dist, speedFlag, endDirState) speedFlag = speedFlag or 0 local npc = self:GetNpc(instance_id) if npc ~= nil then local real_x, real_y = npc:GetRealPos() if GameMath_GetDistance(real_x, real_y, pos_x, pos_y, false) > dist * dist then co.NormaliseXYTable(dir) local end_pos = co.TableXY(pos_x + dir.x * (dist - 10), pos_y + dir.y * (dist - 10)) npc:FindPathAndMove(end_pos) end end end function Scene:MainRoleDirectionMove(dir) if not self.scene_mgr:IsSceneStart() then return end if dir == nil then --松开摇杆,重置寻路状态 self:ResetUserManulState() if not self.main_role or not self.main_role.joy_jump_state then OperateManager.Instance:StopMove() end if self.main_role and self.main_role:CanMove() then self.main_role:ForceSendPos() end self.main_camera:JoyStickState(false) else if self.main_role and self.main_role.story_cfg then return end --手动操作重置状态 local task_change_scene_type = TaskModel:getInstance():GetChangeSceneType() if task_change_scene_type then TaskModel:getInstance():SetChangeSceneType(false, false) end self.main_camera:JoyStickState(true) if not self.main_role or not self.main_role.joy_jump_state then OperateManager.Instance:ClearSrcOper() end if self.main_role then self.main_role:DoDirectionMove(dir) end end end --is_hook 是否挂机 function Scene:MainRoleSkillMove(dir,elapse_time,is_hook) if not self.main_role then return end if dir == nil then self.main_role:DoSkillMoveEnd(dir,elapse_time) return end self.main_camera:JoyStickState(true) if not self.main_role or not self.main_role.joy_jump_state then OperateManager.Instance:ClearSrcOper() end if self.main_role then self.main_role:DoSkillMove(dir,elapse_time,is_hook) end end function Scene:UpdateRole() if self.update_role_name or self.update_role_mode then for id, role in pairs(self.role_list) do if self.update_role_name then role:UpdateName() end if self.update_role_mode then role:ChangeModeHide() end end self.update_role_name = false self.update_role_mode = false end end function Scene:UpdateMonster() if self.update_monster_name then for id, mon in pairs(self.monster_list) do mon:UpdateName() end self.update_monster_name = false end end function Scene:UpdatePartner() if self.update_partner_name then for id, partner in pairs(self.partner_list) do partner:UpdateName() end self.update_partner_name = false end end function Scene:UpdateNpc() end function Scene:LateUpdate(now_time, elapse_time) if not self.scene_data_loaded then return end local cam_pos = self.main_camera:GetCameraPos() if cam_pos then self.mapView:Update( cam_pos ) SapManager:getInstance():Update(cam_pos) end self.is_in_update = true self.late_update_scene_times_index = self.late_update_scene_times_index + 1 self.late_update_elapse_time = self.late_update_elapse_time + elapse_time for _, v in pairs(self.role_list) do if v ~= self.main_role then if v:CanUpdate() then v:Update(now_time, self.late_update_elapse_time) else v:AddIgnoreUpdateIndex() end end end for _, v in pairs(self.other_list) do if v:CanUpdate() then v:Update(now_time, self.late_update_elapse_time) else v:AddIgnoreUpdateIndex() end end for _, v in pairs(self.sprite_list) do if v.IsMainRoleSprite and v:IsMainRoleSprite() then v:MainRoleUpdate(now_time, self.late_update_elapse_time) else if v:CanUpdate() then v:OtherRoleUpdate(now_time, self.late_update_elapse_time) else v:AddIgnoreUpdateIndex() end end end for _, v in pairs(self.evil_list) do if v:CanUpdate() then v:Update(now_time, self.late_update_elapse_time) else v:AddIgnoreUpdateIndex() end end -- for _, v in pairs(self.partner_list) do -- if v:CanUpdate() then -- v:Update(now_time, self.late_update_elapse_time) -- else -- v:AddIgnoreUpdateIndex() -- end -- end for _, v in pairs(self.pet_list) do if v:CanUpdate() then v:Update(now_time, self.late_update_elapse_time) else v:AddIgnoreUpdateIndex() end end for _, v in pairs(self.pokemon_list) do if v:CanUpdate() then v:Update(now_time, self.late_update_elapse_time) else v:AddIgnoreUpdateIndex() end end for _, list in pairs(self.assisit_pokemon_list) do for _,v in pairs(list) do if v:CanUpdate() then v:Update(now_time, self.late_update_elapse_time) else v:AddIgnoreUpdateIndex() end end end for _, v in pairs(self.baby_list) do if v:CanUpdate() then v:Update(now_time, self.late_update_elapse_time) else v:AddIgnoreUpdateIndex() end end for _, v in pairs(self.gwfollower_list) do if v:CanUpdate() then v:Update(now_time, self.late_update_elapse_time) else v:AddIgnoreUpdateIndex() end end for _, v in pairs(self.jump_one_step_list) do --if v:CanUpdate() then v:Update(now_time, self.late_update_elapse_time) --else --v:AddIgnoreUpdateIndex() --end end for _, v in pairs(self.npc_list) do if v:CanUpdate() then v:Update(now_time, self.late_update_elapse_time) else v:AddIgnoreUpdateIndex() end end -- for _, v in pairs(self.door_list) do -- v:Update(now_time, self.late_update_elapse_time) -- end for _, v in pairs(self.drop_list) do if v:IsFinishState() then self:DeleteDropObj(v:GetDropId()) else v:Update(now_time, self.late_update_elapse_time) end end if not lua_viewM.is_lock_screen then for _, v in pairs(self.hook_role_list) do if v:CanUpdate() then v:Update(now_time, self.late_update_elapse_time) else v:AddIgnoreUpdateIndex() end end end self.late_update_elapse_time = 0 self.is_in_update = false --调用延时函数(避免回调过程出错对应列表始终不清空) if not IsTableEmpty(self.delay_handle_funcs) then local delay_funcs = self.delay_handle_funcs self.delay_handle_funcs = {} for _, v in pairs(delay_funcs) do if v then v() end end end if not self.scene_mgr:IsSceneStart() then return end if self.late_update_scene_times_index % 13 == 0 then self:UpdateRole() end if self.late_update_scene_times_index % 13 == 0 then self:UpdateMonster() end -- if self.late_update_scene_times_index % 20 == 0 then -- self:UpdateNpc() -- end if rawget(self, "main_role") and not self.main_role.disabled then if self.late_update_scene_times_index % 7 == 0 then self:UpdateAutoFight() elseif self.late_update_scene_times_index % 61 == 0 then self:UpdateClickTargetEffect() elseif self.late_update_scene_times_index % 101 == 0 then self:UpdateRoleVisibleState() end end if self.last_find_jump_nearest_vo_time and Time.time - self.last_find_jump_nearest_vo_time > 3 then print("tanar: [Scene 3904]=> self.last_find_jump_nearest_vo_time: ",self.last_find_jump_nearest_vo_time) self.last_find_jump_nearest_vo_time = nil end local guild_model = GuildModel:getInstance() if self.scene_mgr:IsPetDungeon() then --宠物副本需要检测buff球距离 if self.late_update_scene_times_index % 25 == 0 then self:CheckBuffBall() end elseif self.scene_mgr:IsGuildScene() and guild_model:IsGuildCollectActive() then --社团封印裂隙活动自动采集状态需要自动寻路去找采集怪 if self.late_update_scene_times_index % 31 == 0 and guild_model:IsAutoGuildCollectState() then --只在角色站立不动没事干且状态为自动社团采集状态时才执行自动寻路逻辑 if self.main_role:IsInState(PoseState.WAITSTAND) or self.main_role:IsInState(PoseState.STAND) then guild_model:Fire(GuildModel.AUTO_FIND_WAY_TO_GUILD_COLLECT_MON) end end elseif self.scene_mgr:IsGuildCSGRScene() and guild_model:IsCSGRInCollectRound() then -- 本国团战如果处于采集阶段并激活了自动采集则需要自动寻找最近的采集物 if self.late_update_scene_times_index % 62 == 0 and guild_model:GetCSGRAUtoCollectStatus() then -- 只在角色站立不动没事干且状态为自动采集状态时才执行自动寻路逻辑 if self.main_role:IsInState(PoseState.WAITSTAND) or self.main_role:IsInState(PoseState.STAND) then guild_model:CSGRAutoCollect() end end -- elseif (self.escort_model and self.escort_model:IsEscortState() and self.escort_model.not_pause ) or (EscortModel:GetInstance():IsEscortState() and EscortModel:GetInstance().not_pause )then--在护送的时候要检测怪的距离(暂时 不确定性能会不会有很大影响 应该不会) -- self:CheckEscortDistance() end end function Scene:Update( now_time, elapse_time ) local preload_max_time = self.preload_max_time -- if self.is_first_enter_game or self.is_first_enter_scene or self.load_scene_timeout_max then -- preload_max_time = preload_max_time * 2 -- end -- if SystemMemoryLevel.Cur == SystemMemoryLevel.Hight then -- preload_max_time = preload_max_time * 0.75 -- end --预加载超时关闭 if self.start_preload_sceneObjRes_time and now_time - self.start_preload_sceneObjRes_time >= preload_max_time then self:PreLoadSceneObjResCompleted() if self.sceneLoadView then self.load_progress_finished = true self.scene_data_loaded = true self.sceneLoadView.scene_load_progress_finished = true self.start_preload_sceneObjRes_time = nil end GlobalEventSystem:Fire(EventName.TIMEOUT_ENTER_SCENE) end if self.sceneLoadView and self.sceneLoadView:HasOpen() then -- if self.sceneLoadView.scene_load_progress_finished and self.scene_data_loaded and self.preload_res_is_loaded then if self.sceneLoadView.scene_load_progress_finished and self.scene_data_loaded then LuaMemManager:getInstance():checkToReleaseMem(true) self.load_progress_finished = true self:CloseSceneLoadView() GlobalEventSystem:Fire(EventName.NOTICE_SCENE_LOAD_WILL_COMPLETE) self.scene_load_view_complete_time = Time.time end if not self.sceneLoadView.hide_load_progress then return end end if self.main_role then self.main_role:Update(now_time, elapse_time) if self.find_monster_pos then local x,y = self.main_role:GetRealPos() if GameMath_GetDistance(x,y,self.find_monster_pos.x,self.find_monster_pos.y,false) <= self.find_monster_distance * self.find_monster_distance then local attack_list = self:FindTargets(Scene.FIND_TARGET_TYPE.all, 1, nil, self.find_monster_distance, nil, nil, nil, nil, nil, nil, nil, nil, nil, true,nil,false) if attack_list and attack_list[1] then if self.main_role:GetMainRoleInBabyDunFlag() then -- 宝宝副本,走宝宝副本的挂机技能 self.SkillMgr:PrepareAutoFightSkillInBabyDun() else self.SkillMgr:PrepareAutoFightSkill() end local obj_type = attack_list[1].obj_type if obj_type == SceneBaseType.Role then self:MainRoleAttackRole(attack_list[1]) elseif obj_type == SceneBaseType.Monster then self:MainRoleAttackMonster(attack_list[1]) end self.find_monster_pos = false GlobalEventSystem:Fire(EventName.STARTAUTOFIGHT) end end end end self.update_scene_times_index = self.update_scene_times_index + 1 self.update_elapse_time = self.update_elapse_time + elapse_time if not lua_viewM.is_lock_screen then for _, v in pairs(self.monster_list) do if v:CanUpdate() then v:Update(now_time, self.update_elapse_time) else v:AddIgnoreUpdateIndex() end end end --正在渐隐的的怪物尸体 for _, v in pairs(self.dead_body_list) do if v:CanUpdate() then v:Update(now_time, self.update_elapse_time) else v:AddIgnoreUpdateIndex() end end self.update_elapse_time = 0 end function Scene:UpdateAllMonsterVisible() if self.scene_mgr:IsNotBlockMonsterScene() then return end for id, mon in pairs(self.monster_list) do if self.is_hide_all_mon then if not mon:HasModelHideFlag(SceneObj.ModelHideFlag.RoleNumLimit) then mon:SetModelHideFlag(SceneObj.ModelHideFlag.RoleNumLimit, true) end else if mon:HasModelHideFlag(SceneObj.ModelHideFlag.RoleNumLimit) then mon:SetModelHideFlag(SceneObj.ModelHideFlag.RoleNumLimit, false) end end end end --更新玩家显示状态 function Scene:UpdateRoleVisibleState(force_to_check) if self.check_visible_role_num_time == false or Time.time - self.check_visible_role_num_time > 10 or force_to_check then self.check_visible_role_num_time = Time.time --设置的同屏玩家数量 local player_limit_setting_count = 0 if not LuaViewManager:getInstance().is_lock_screen then player_limit_setting_count = (lua_settingM:GetBlockProperty("other") or self.is_hide_all_role) and 0 or lua_settingM:GetPlayerCounts() end -- local mainRole_defender_list = self.scene_mgr.mainRole_defender_list --攻击过主角的角色 local invisible_list = {} --场景角色列表按距离排序 local base_dis_offset for id, role in pairs(self.role_list) do base_dis_offset = 160000 --可操作的偏移距离 if role ~= self.main_role and (not role:IsModelHiden() or role:HasModelHideFlag(SceneObj.ModelHideFlag.RoleNumLimit)) then --除了人数限制的隐藏 其他情况的隐藏不受控制 --5秒内攻击过我的玩家,先拿出来 -- if mainRole_defender_list[role.id] and Time.time - mainRole_defender_list[role.id].start_time < 5 then -- base_dis_offset = 0 -- end local x1, y1 = role:GetRealPos() local x2, y2 = self.main_role:GetRealPos() role.dist_to_main_role = GameMath_GetDistance(x1, y1, x2, y2, false) + base_dis_offset table_insert(invisible_list, role) end end local sort_func = function (a, b) return a.dist_to_main_role < b.dist_to_main_role end table_sort(invisible_list, sort_func) local need_show = false local curr_show_player_count = 0 --当前已经显示的玩家数量 for i = 1, #invisible_list do local role = invisible_list[i] if curr_show_player_count < player_limit_setting_count then need_show = true else need_show = false end if need_show then -- 需要渲染的人放进渲染列表 if role:HasModelHideFlag(SceneObj.ModelHideFlag.RoleNumLimit) then role:SetModelHideFlag(SceneObj.ModelHideFlag.RoleNumLimit, false) --显示回来的角色,如果死亡就继续躺着 if not role:IsModelHiden() and role:IsDead() then role:PlayDeadNormalized() end end curr_show_player_count = curr_show_player_count + 1 else if not role:HasModelHideFlag(SceneObj.ModelHideFlag.RoleNumLimit) then role:SetModelHideFlag(SceneObj.ModelHideFlag.RoleNumLimit, true) end end end end end function Scene:ChangeTarget(find_target_type, distance, area, check_invincible) find_target_type = find_target_type or Scene.FIND_TARGET_TYPE.all area = area or 1000 local center_pos = co.TableXY(self.main_role:GetRealPos()) local attack_list, role_list = self:FindTargets(Scene.FIND_TARGET_TYPE.all, 10, distance, area, nil, nil, center_pos, nil, nil, nil, nil, nil, nil, true,nil,false) for i,role in ipairs(role_list) do table_insert(attack_list,role) end for k,obj in pairs(attack_list) do if obj == self.curr_click_target then table.remove(attack_list,k) break end end if check_invincible then -- 是否需要检查是否处于无敌状态 for k,obj in pairs(attack_list) do if self:IsMonsterInvincible(obj) then table.remove(attack_list,k) end end end local num = attack_list and #attack_list or 0 local target = attack_list and attack_list[math.random(1,num)] if target then self.manual_target = target self:SetClickTarget(target) --切换目标头像 if target:GetType() == SceneBaseType.Role then self.scene_mgr:SetAttackHeadVo(target.vo, nil, true) elseif target:GetType() == SceneBaseType.Monster then self.scene_mgr:ResetAttackHeadVo(true) end return target end return nil end function Scene:SetEnterSceneFlag() --[[ if self.scene_mgr:IsPkBattleScene() then self.target_auto_fight_cfg = Config.ConfigTargetAutoFight.Flag["PkBattleScene"] elseif self.scene_mgr:IsGuildWarScene() then self.target_auto_fight_cfg = DeepCopy(Config.ConfigTargetAutoFight.Flag["GuildWarScene"]) elseif self.scene_mgr:IsGuildGuardDungeon() then self.target_auto_fight_cfg = Config.ConfigTargetAutoFight.Flag["GuildGuardDungeon"] elseif self.scene_mgr:IsMainCityAndFieldScene() then self.target_auto_fight_cfg = Config.ConfigTargetAutoFight.Flag["MainCityAndFieldScene"] elseif self.scene_mgr:IsOnButterflyScene() then self.target_auto_fight_cfg = Config.ConfigTargetAutoFight.Flag["ButterflyScene"] elseif self.scene_mgr:IsEquipScene() then self.target_auto_fight_cfg = Config.ConfigTargetAutoFight.Flag["DungeonEquipScene"] elseif self.scene_mgr:IsRefineDungeon() then self.target_auto_fight_cfg = Config.ConfigTargetAutoFight.Flag["DungeonRefineScene"] elseif self.scene_mgr:IsStarDungeonScene() then self.target_auto_fight_cfg = Config.ConfigTargetAutoFight.Flag["StarDungeonScene"] elseif self.scene_mgr:IsKFGuildWarFightScene() then self.target_auto_fight_cfg = Config.ConfigTargetAutoFight.Flag["KFGuildWarFightScene"] elseif self.scene_mgr:IsDiamondFightScene() then self.target_auto_fight_cfg = Config.ConfigTargetAutoFight.Flag["DiamonFightScene"] elseif self.scene_mgr:IsLoveDungeon() then self.target_auto_fight_cfg = Config.ConfigTargetAutoFight.Flag["DungeonLoveScene"] elseif self.scene_mgr:IsOvnFightingScene() then self.target_auto_fight_cfg = Config.ConfigTargetAutoFight.Flag["CSOnevNScene"] elseif self.scene_mgr:IsCSPvP() then self.target_auto_fight_cfg = Config.ConfigTargetAutoFight.Flag["Cross3v3"] --- 明日项目新增的写在这下面 elseif self.scene_mgr:IsMaterialDungeon() then self.target_auto_fight_cfg = Config.ConfigTargetAutoFight.Flag["IsMaterialDungeon"] elseif self.scene_mgr:IsExpDun() then self.target_auto_fight_cfg = Config.ConfigTargetAutoFight.Flag["IsExpDungeon"] else self.target_auto_fight_cfg = Config.ConfigTargetAutoFight.Flag["Default"] end if self.scene_mgr:IsMainCityAndFieldScene() then self.pick_drop_distance = 1000 else self.pick_drop_distance = 3000 end if self.scene_mgr:IsGuildBossDungeon() or self.scene_mgr:IsSingleDungeon() or self.scene_mgr:IsBossEvilScene() or self.scene_mgr:IsBossHomeScene() or self.scene_mgr:IsBossForbiddenScene() then self.only_main_role_pick = true else self.only_main_role_pick = false end if self.scene_mgr:IsBossEvilScene() or self.scene_mgr:IsBossHomeScene() or self.scene_mgr:IsBossForbiddenScene() then self.need_change_move_speed = true else self.need_change_move_speed = false end ]] self.target_auto_fight_cfg = {} self.target_auto_fight_cfg.distance = 100000 if self.scene_mgr:IsMainCityAndFieldScene() then self.target_auto_fight_cfg.distance = 1000 end self.find_monster_distance = self.target_auto_fight_cfg.distance or 1000 end function Scene:CanOptJoyStick() return self.can_opt_joy_stick end function Scene:UpdateAutoFindTarget(manual_distance) if self.main_role and self.main_role:GetIsCollecting() then--已经在采集中就不要去找怪打了 return end local distance = manual_distance or self.target_auto_fight_cfg.distance local attack_mon, attack_role local first_attack = Scene.FIND_TARGET_TYPE.monster --self.auto_fight_mgr:GetTargetFirstAttack() --获取优先攻击类型 if self.scene_mgr:IsCSPvP() or self.scene_mgr:IsDiamondFightScene() or self.scene_mgr:IsEndlessLastScene() or self.scene_mgr:IsWastelandScene() then first_attack = Scene.FIND_TARGET_TYPE.role end local attack_list = {} if self.scene_mgr:IsFixedPointFightScene() then local center_pos = self.auto_fight_mgr:GetFixedPointPos() or co_TableXY(self.main_role:GetRealPos()) local area = 600 ------------------------------------------------特殊处理START if self.scene_mgr:IsPetDungeon() then--宠物副本改成获取场景出生点,以及扩大索敌范围 center_pos = co_TableXY(self.scene_mgr:GetSceneBirthPos()) area = 1000 end ------------------------------------------------特殊处理END attack_list = self:FindTargets(Scene.FIND_TARGET_TYPE.monster, 1, nil, area, nil, nil, center_pos) if #attack_list == 0 and self.auto_fight_mgr:GetAutoFightState() then local rx, ry = self.main_role:GetRealPos() ------------------------------------------------特殊处理START if self.scene_mgr:IsPetDungeon() then--宠物副本 --宠物副本挂机逻辑:先杀怪,没怪先捡buff,没buff回原点 local dun_pet_buff_list = BaseDungeonModel:getInstance():GetBuffPosList() if #dun_pet_buff_list ~= 0 then self:ClearDunPetTimer() local buff_distance = 999999999 local need_to_buff_pos = nil for i,v in ipairs(dun_pet_buff_list) do local pos = co_TableXY(v.x,v.y) local dis = GameMath_GetDistance(pos.x, pos.y, rx, ry, false) if dis area*300 then self.main_role:DoMove(center_pos) end end if not self.dun_pet_stand_delay_timer_id then self.dun_pet_stand_delay_timer_id = setTimeout(delay_method, 1) end end return end ------------------------------------------------特殊处理END if GameMath_GetDistance(center_pos.x, center_pos.y, rx, ry, false) > area*area then self.main_role:DoMove(center_pos) end return end else ------------------------------------------------特殊处理START self:ClearDunPetTimer()--清除宠物副本的定时回家计时器 ------------------------------------------------特殊处理END --除非指明需要优先找人,其他情况都优先找怪 if first_attack == Scene.FIND_TARGET_TYPE.role then attack_role = self:FindNearestRole(nil, distance) if not attack_role then local need_find_collection = false --先杀人 然后去抢箱子 if self.scene_mgr:IsEndlessLastScene() or self.scene_mgr:IsWastelandScene() then need_find_collection = true end attack_mon = self:FindNearestMonster(nil, distance, need_find_collection) end else attack_mon = self:FindNearestMonster(nil, distance, false) if not attack_mon then attack_role = self:FindNearestRole(nil, distance) end end end local attack_target = nil if attack_list and attack_list[1] then attack_target = attack_mon or attack_role or attack_list[1] else attack_target = attack_mon or attack_role end if attack_target then ------------------------- --自动战斗的选中,也要显示一下头像 if attack_target:GetType() == SceneBaseType.Role then GlobalEventSystem:Fire(EventName.SHOW_OTHER_HEAD, true, attack_target.vo, 1) end ------------------------- self:SetClickTarget(attack_target) end end --清除宠物副本的定时回家计时器 function Scene:ClearDunPetTimer( ) if self.dun_pet_stand_delay_timer_id then GlobalTimerQuest:CancelQuest(self.dun_pet_stand_delay_timer_id) self.dun_pet_stand_delay_timer_id = nil end end --是否有掉落可等待拾取 function Scene:HasDropPick( ) --背包格子是否满了 if GoodsModel:getInstance():GetEmptyGrid() <= 0 then return false end local vo = self:FindDropItem(1000) if vo and vo[1] and vo[2] then local drop = vo[1] local dis = vo[2] -- if drop and drop:IsCanPickUp() and not drop:IsPicking() and OffLineModel:getInstance():IsDropCanAutoPick(drop.color) then if drop and drop:IsCanPickUp() and not drop:IsPicking() then return true end end end function Scene:OnPick() --走过去一个个捡 local vo = self:FindDropItem(self.pick_drop_distance) if vo and vo[1] and vo[2] then local drop = vo[1] local dis = vo[2] if drop and drop:IsCanPickUp() and not drop:IsPicking() then if self.need_change_move_speed then self.main_role.move_flag = MOVE_TYPE.PICK_DROP end local x, y = drop:GetRealPos() self:MainRoleMove(co.TableXY(x / SceneObj_LogicRealRatio_x, y / SceneObj_LogicRealRatio_y), 0) return true end end end --守护拾取 function Scene:OnEvilPick() --在一键拾取过程中,不要再去捡东西 is_in_pick_all_state --走过去一个个捡 local vo = self:FindDropItem(self.pick_drop_distance, true) if not self.is_in_pick_all_state and vo and vo[1] and vo[2] then local drop = vo[1] local dis = vo[2] if drop and drop:IsCanPickUp() and not drop:IsPicking() and self.main_role and self.main_role.evil then local x, y = drop:GetRealPos() self.main_role.evil:OnPick(co.TableXY(x, y), drop) return false end end if self.main_role and self.main_role.evil then self.main_role.evil:CancelPick() end return false end function Scene:AutoPick() local is_dialogue_is_open = DialogueModel:getInstance().dialogue_is_open local is_empty_bag = GoodsModel:getInstance():GetEmptyGrid()==0 local is_guild_scene = self.scene_mgr:IsGuildScene() local is_collecting = self.scene_mgr:GetCollectFlag() if is_dialogue_is_open or (is_collecting and not is_guild_scene) or is_empty_bag or self.is_in_pick_all_state then return end --是否穿戴了守护(并且守护已经创建出来了) if not self.only_main_role_pick and not SceneManager:getInstance():IsGuildScene() and ItemUseModel:getInstance():HasWearEvil() and self.main_role and self.main_role.evil then return self:OnEvilPick() else return self:OnPick() end end function Scene:UpdateAutoFight() if not self.auto_fight_mgr:GetAutoFightState() then return end if not self.auto_fight_mgr.game_running then return end if self.scene_mgr:IsPreChangeSceneState() then return end if not self.load_progress_finished then return end if not UserMsgAdapter:getInstance():IsGameConnected() then return end --过来最小攻击间隔和寻怪间隔 if (Status.NowTime - self.last_attack_time < self.auto_find_and_attack_interval or Status.NowTime - self.last_find_target_time < self.auto_find_and_attack_interval) then return end if not self.main_role or self.main_role:IsDead() or self.main_role:IsInState(PoseState.TASK_JUMP) or self.mainrole_vo.hp <= 0 or self.mainrole_vo.ghost_mode == 1 or self.main_role:IsInState(PoseState.STORY) then return end -- if self.auto_fight_mgr.go_to_pos and self.auto_fight_mgr.go_to_pos.scene_id == self.scene_mgr:GetSceneId() and self.main_role:CanMove() then -- local pos = self.auto_fight_mgr.go_to_pos -- if self.scene_mgr:IsBlockXY(pos.x, pos.y) then -- pos = co.Vector2(SourceOperateMove.FindNearestPos(co.TableXY(self.main_role.real_pos.x,self.main_role.real_pos.y),pos)) -- end -- local end_function = function () -- self.user_manul_time = Status.NowTime -- end -- self:ClearLastAttack() -- self.auto_fight_mgr:CacheGoToPos() -- self.user_manul_time = Status.NowTime + 0.5 -- self:MainRoleMove(co.TableXY(pos.x / SceneObj_LogicRealRatio_x, pos.y / SceneObj_LogicRealRatio_y), 1, end_function) -- return -- end if Status.NowTime - self.user_manul_time < 0.5 then return end if self.auto_fight_mgr.auto_find_way then return end --是否在施法僵直的过程中 if self.SkillMgr:GetRigidityLeftTime() > 0.5 then return end --优先自动拾取 if self:AutoPick() then return else --判断拾取完是否需要触发自动任务, 现在的逻辑就是做任务过程优先拾取掉落 if self.need_task_after_pick then self.need_task_after_pick = false GlobalEventSystem:Fire(EventName.FORCE_TO_DO_TASK) end end local is_mainrole_in_babydun = self.main_role:GetMainRoleInBabyDunFlag() if is_mainrole_in_babydun then -- 宝宝副本需要走另一套自动挂机逻辑 if not self.SkillMgr:PrepareAutoFightSkillInBabyDun(true) then return end else -- print("Saber:Scene [4396] is_mainrole_in_babydun: ",is_mainrole_in_babydun) if not self.SkillMgr:PrepareAutoFightSkill(true) then return end end if self.curr_click_target and self.curr_click_target:IsDead() == false then if self.curr_click_target.obj_type == SceneBaseType.Role then self:MainRoleAttackRole(self.curr_click_target) elseif self.curr_click_target.obj_type == SceneBaseType.Monster then --封印裂隙在次数满了之后禁止自动前往采集选中的采集怪 if self.curr_click_target:GetVo().type == MonsterType.COLLECT and SceneManager:getInstance():IsGuildScene() then if not GuildModel.Instance:CanCollect() and GuildModel.Instance:IsGuildCollectActive() then return end end self:MainRoleAttackMonster(self.curr_click_target,nil,true) -- local next_skill = self.SkillMgr:GetNextSkill() -- self.SkillMgr:AddCacheSkill(next_skill, 2) else self:UpdateAutoFindTarget() end else self:UpdateAutoFindTarget() end end --获取上次攻击的对象 function Scene:GetAutoFightLastAttack(obj) local target = nil if obj == nil then return target end if obj:GetType() == SceneBaseType.Monster then target = self:GetMonster(obj.id) elseif obj:GetType() == SceneBaseType.Role then target = self:GetRole(obj.id) end return target end function Scene:ClearLastAttack() if self.last_ranAttackObj then self.last_ranAttackObj = nil end end --手动放技能攻击目标 function Scene:MainRoleAttackTarget() local function on_find_target_to_attack( ) self:UpdateAutoFindTarget(self.pre_check_distance) if self.curr_click_target then if self.curr_click_target:GetType() == SceneBaseType.Monster then self:MainRoleAttackMonster(self.curr_click_target) elseif self.curr_click_target:GetType() == SceneBaseType.Role then self:MainRoleAttackRole(self.curr_click_target, nil, true) else GlobalEventSystem:Fire(FightEvent.RELEASE_MAIN_SKILL) end else GlobalEventSystem:Fire(FightEvent.RELEASE_MAIN_SKILL) end end if self.curr_click_target then if self.curr_click_target:GetType() == SceneBaseType.Monster then --当前目标为怪物 self:MainRoleAttackMonster(self.curr_click_target) elseif self.curr_click_target:GetType() == SceneBaseType.Role then --当前目标为角色 self:MainRoleAttackRole(self.curr_click_target, nil, true) else --当前目标为不可攻击对象,要重新预选 self:CancelClickTarget() self.manual_target = false on_find_target_to_attack() end else --当前无目标,尝试找个攻击对象 on_find_target_to_attack() end end --采集怪物 function Scene:MainRoleCollectMonster(monster,is_auto_fight) if monster == nil or monster:IsDead() then return end if self.main_role and self.main_role:IsInState(PoseState.COLLECT) then return end local action_func = function() if self.mainrole_vo.ghost_mode == 1 and monster:GetVo() and(monster:GetVo().type == MonsterType.COLLECT or monster:GetVo().type == MonsterType.TASK_COLLECT or monster:GetVo().type == MonsterType.UD_COLLECT) then Message.show("您处于幽灵模式,不能进行采集!") return end if monster:IsDead() then--or (monster.cfg_data and monster.cfg_data.kind == 7) then --塔类怪物不攻击 return end --社团采集活动,采集次数满了之后不允许再采集 if SceneManager:getInstance():IsGuildScene() then if not GuildModel.Instance:CanCollect() and GuildModel.Instance:IsGuildCollectActive() then local reason = GuildModel.Instance:GetCanNotCollectReason() if reason == 1 then Message.show("本场封印次数已满!请下场再来") elseif reason == 2 then Message.show("本日封印次数已满,请明日再来") end self:CancelClickTarget(nil,true) --把目标清掉 self.main_role:DoStand(true) return end end if monster:GetVo().type == MonsterType.COLLECT or monster:GetVo().type == MonsterType.UD_COLLECT or monster:GetVo().type == MonsterType.MISSION_COLLECT then --普通采集|不死采集|副本采集 --如果是自动采集,采集同一个采集物,采集成功后,要有300ms 冷却时间,防止跨域中怪物没被删除 if is_auto_fight then local time = TimeUtil:getServerTimeMs() if self.last_auto_pick_id and monster.id == self.last_auto_pick_id and time - self.last_auto_pick_time < 300 then return end self.last_auto_pick_id = false self.last_auto_pick_time = false end GlobalEventSystem:Fire(EventName.OPEN_COLLECT_VIEW, monster.id, monster:GetVo().type_id, monster:GetVo().pick_time) return end if monster:GetVo().type == MonsterType.TASK_COLLECT then --任务采集 local have_task, monster_id = TaskModel:getInstance():HaveCaiJiTask(monster:GetVo().type_id) if have_task and monster_id and monster:GetVo().type_id == monster_id then local is_fake = false if GuideModel.MONSTER_COLLECT[monster_id] then is_fake = true end local call_back = function ( ) DialogueModel:getInstance():Fire(DialogueModel.REQUEST_CCMD_EVENT, 30015, TaskTipType.TYPE18, monster_id) end GlobalEventSystem:Fire(EventName.OPEN_COLLECT_VIEW, monster.id, monster:GetVo().type_id, monster:GetVo().pick_time, is_fake, call_back) end end end --增加跨服boss增加采集物拾取范围判断 local attack_range = 150 if monster:GetVo() and monster:GetVo().type_id then if (monster:GetVo().type_id == Config.ConfigTaskEffect.MonsterSakuraTypeID or monster:GetVo().type_id == Config.ConfigTaskEffect.MonsterCarouselTypeID) then attack_range = 400 elseif monster:GetVo().type_id == Config.ConfigTaskEffect.MonsterLightTypeID then attack_range = 300 end end if self.main_role == nil then return end local target_obj = monster if self.collect_target_start_real_pos == nil then self.collect_target_start_real_pos = co_TableXY(self.main_role:GetRealPos()) else self.collect_target_start_real_pos.x = self.main_role.real_pos.x self.collect_target_start_real_pos.y = self.main_role.real_pos.y end if self.collect_target_end_real_pos == nil then self.collect_target_end_real_pos = co_TableXY(target_obj:GetRealPos()) else self.collect_target_end_real_pos.x = target_obj.real_pos.x self.collect_target_end_real_pos.y = target_obj.real_pos.y end local distance = GameMath_GetDistance(self.collect_target_start_real_pos.x, self.collect_target_start_real_pos.y, self.collect_target_end_real_pos.x, self.collect_target_end_real_pos.y, false) if distance <= attack_range * attack_range then if self.main_role:IsInState(PoseState.MOVE) then --转向目标,然后站立 self.main_role:SetDirection(self.collect_target_start_real_pos, self.collect_target_end_real_pos, true, true) self.main_role:DoStand() end action_func() elseif self.main_role:CanMove() then self.last_find_target_time = Time.time OperateManager.Instance:StartTargetAction(monster.compress_id, attack_range, action_func) end end function Scene:MainRoleAttackMonster(monster,not_rush,is_auto_fight) if monster == nil or monster:IsDead() then return end if not self.main_role or self.main_role:IsInState(PoseState.RUSH) then return end --采集怪物不走冲刺逻辑 if monster:GetVo().type == MonsterType.COLLECT or monster:GetVo().type == MonsterType.TASK_COLLECT or monster:GetVo().type == MonsterType.UD_COLLECT then self:SetClickTarget(monster) self:MainRoleCollectMonster(monster,is_auto_fight) return end local skill_id = self.SkillMgr:getCurrentSkillId() local cfg = self.SkillMgr:GetFightSkillMovie(skill_id) if not self.SkillMgr:CanAttack(skill_id) then return end --到目标点后放技能 local function use_skill_func() if not self.SkillMgr:isInRigidity() then self.last_attack_time = Time.time GlobalEventSystem:Fire(FightEvent.RELEASE_MAIN_SKILL, nil, nil, monster.compress_id) else print("tanar: Scene [4970] =========== isInRigidity") end end local function rush_action_func( ) if monster:IsDead() then return end if self.need_rush_to_monster then local offset = Config.otherFightInfo.rush_to_monster_offset_dis if monster.vo and monster.vo.boss_type > 2 then offset = 300 end if self.rush_mon_end_pos == nil then self.rush_mon_end_pos = co_TableXY(self.attack_mon_end_real_pos.x - self.rush_mon_end_dir.x * offset, self.attack_mon_end_real_pos.y - self.rush_mon_end_dir.y * offset) else self.rush_mon_end_pos.x = self.attack_mon_end_real_pos.x - self.rush_mon_end_dir.x * offset self.rush_mon_end_pos.y = self.attack_mon_end_real_pos.y - self.rush_mon_end_dir.y * offset end if self.scene_mgr:IsBlockXY(self.rush_mon_end_pos.x / SceneObj_LogicRealRatio_x, self.rush_mon_end_pos.y / SceneObj_LogicRealRatio_y) then self.rush_mon_end_pos.x = monster.real_pos.x self.rush_mon_end_pos.y = monster.real_pos.y end local rush_speed = Config.otherFightInfo.rush_to_monster_speed self.main_role:DoRush(self.rush_mon_end_pos, rush_speed, use_skill_func) else use_skill_func() end end --是否需要冲刺 self.need_rush_to_monster = false --设置当前选中目标,避免重复筛选 self:SetClickTarget(monster) --在攻击前如果还没设置技能,就要先设置一个技能,以便进行攻击距离判断 if self.is_in_babydun then if self.SkillMgr:getCurrentSkill() == nil then self.SkillMgr:setCurrentSkillId(SkillManager.BabyDunMainRoleBaseSkill) end else if self.SkillMgr:getCurrentSkill() == nil or self.SkillMgr:IsThreeAttackSkill(skill_id) then self.SkillMgr:setCurrentSkillId(self.SkillMgr:getBaseSkill()) end end local target_obj = monster -- local attack_range = self.SkillMgr:GetCurrentAttackRange() local attack_range = 350 if target_obj and self.scene_mgr:IsEscortScene() and target_obj:GetVo().type == MonsterType.ESCORT and target_obj:GetVo().can_attack ~= 1 then --如果打的是护送怪,并且不可以被攻击,就提示玩家对应的东西 --进行严格判断,只会满足上面的判断才会进来,并且两秒才提示一次 local function callback( ) local str = "车辆不可伤害,请先击败护送者" if target_obj and target_obj:GetVo() and target_obj:GetVo().hp == 1 then str = "车辆受损,物资已被夺取" end Message.show(str) end TimeManager.GetInstance():StartDalayTime("ShowEscortMessage",2,callback) -- elseif target_obj and self.scene_mgr:IsRageWarScene() and target_obj:GetVo().boss_type == BossType.UnDead -- 狂战领域追加了横幅,这个暂时屏蔽 -- and target_obj:GetBuffVoByBuffTypeAndBuffId(SkillBuffType.UNBEATABLE, 1110000015) then -- 获取无敌buff -- -- 狂战领域boss无敌时,主动攻击要弹出飘字,内容由阶段数决定 -- local event_data = RageWarModel:getInstance():GetRageWarEventData() -- if event_data then -- local function callback( ) -- local str = event_data.round >= RageWarModel.EventStatus.Round2 and "吸取分身能量中" or "吸取同伴能量中" -- Message.show(str) -- end -- TimeManager.GetInstance():StartDalayTime("ShowRageWarMessage", 2, callback) -- end end if self.attack_mon_start_real_pos == nil then self.attack_mon_start_real_pos = co_TableXY(self.main_role:GetRealPos()) else self.attack_mon_start_real_pos.x = self.main_role.real_pos.x self.attack_mon_start_real_pos.y = self.main_role.real_pos.y end if self.attack_mon_end_real_pos == nil then self.attack_mon_end_real_pos = co_TableXY(target_obj:GetRealPos()) else self.attack_mon_end_real_pos.x = target_obj.real_pos.x self.attack_mon_end_real_pos.y = target_obj.real_pos.y end if self.rush_mon_end_dir == nil then self.rush_mon_end_dir = co_TableXY(self.attack_mon_end_real_pos.x-self.attack_mon_start_real_pos.x, self.attack_mon_end_real_pos.y-self.attack_mon_start_real_pos.y) else self.rush_mon_end_dir.x = self.attack_mon_end_real_pos.x - self.attack_mon_start_real_pos.x self.rush_mon_end_dir.y = self.attack_mon_end_real_pos.y - self.attack_mon_start_real_pos.y end self.rush_mon_distance = co_NormaliseXYTable(self.rush_mon_end_dir) local max_rush_dis = Config.otherFightInfo.rush_to_monster_max_dis if self.rush_mon_distance <= attack_range then --在最小范围内,直接放技能 self.need_rush_to_monster = false if self.main_role:IsInState(PoseState.MOVE) then --转向目标,然后站立 self.main_role:SetDirection(self.attack_mon_start_real_pos, self.attack_mon_end_real_pos, true, true) self.main_role:DoStand() end use_skill_func() elseif self.rush_mon_distance <= max_rush_dis then if target_obj and self.is_in_babydun then -- 宝宝副本内,走过去打 self.last_find_target_time = Time.time OperateManager.Instance:StartTargetAction(monster.compress_id, attack_range, use_skill_func) else --在冲刺范围内,直接冲刺 self.need_rush_to_monster = true self.last_find_target_time = Time.time rush_action_func() end else if target_obj and self.is_in_babydun then -- 宝宝副本内,走过去打 self.last_find_target_time = Time.time OperateManager.Instance:StartTargetAction(monster.compress_id, attack_range, use_skill_func) else --超过冲刺范围,先移动,再冲刺 self.need_rush_to_monster = true self.last_find_target_time = Time.time OperateManager.Instance:StartTargetAction(monster.compress_id, max_rush_dis, rush_action_func) end end end function Scene:MainRoleAttackRole(role, not_rush, ignore_check_pk_state) if role == nil or role:IsDead() or role == self.main_role then return end --是否需要检查PK状态(手动释放技能不需要检查,就算打不了也要给他放技能) if not ignore_check_pk_state and not self.scene_mgr:IsCanAttackByMainRole(role:GetVo()) then return end if self.mainrole_vo.ghost_mode == 1 then Message.show("您处于幽灵模式,不能进行攻击") return end if self.main_role and self.main_role:IsInState(PoseState.RUSH) then return end local skill_id = self.SkillMgr:getCurrentSkillId() local cfg = self.SkillMgr:GetFightSkillMovie(skill_id) if not self.SkillMgr:CanAttack(skill_id) then return end if cfg and cfg.rush_dist and cfg.rush_dist < 0 then--如果是往后跳的技能,就直接放掉而不追踪 action_func() return end --到目标点发技能 local use_skill_func = function() if not self.SkillMgr:isInRigidity() then self.last_attack_time = Time.time GlobalEventSystem:Fire(FightEvent.RELEASE_MAIN_SKILL, nil, nil, role.compress_id) else print("tanar: Scene [5091] =========== isInRigidity") end end --移动完成回调 local rush_action_func = function() if role == nil or role:IsDead() or not role:IsVoValid() then return end if role:IsInProtectTime() then Message.show("目标处于无敌状态") return end if self.scene_mgr:IsSafePos(role.real_pos.x, role.real_pos.y) then --如果被攻击的角色在安全区里,提示 self:CancelClickTarget(nil, true) Message.show("对方在安全区中,无法攻击") return end -- if (not self.scene_mgr:IsEscortScene()) and role.vo and role.vo.escort_state>0 then -- Message.show("该玩家为护送第一阶段,无法攻击") -- return -- end if self.need_rush_to_role then -- local end_pos = co_TableXY(self.attack_role_end_real_pos.x - self.rush_role_end_dir.x * Config.otherFightInfo.rush_to_monster_offset_dis, self.attack_role_end_real_pos.y - self.rush_role_end_dir.y * Config.otherFightInfo.rush_to_monster_offset_dis) -- if self.scene_mgr:IsBlockXY(end_pos.x / SceneObj_LogicRealRatio_x, end_pos.y / SceneObj_LogicRealRatio_y) then -- end_pos.x = role.real_pos.x -- end_pos.y = role.real_pos.y -- end -- self.main_role:DoRush(end_pos, Config.otherFightInfo.rush_to_monster_speed, use_skill_func) local offset = Config.otherFightInfo.rush_to_monster_offset_dis if self.rush_role_end_pos == nil then self.rush_role_end_pos = co_TableXY(self.attack_role_end_real_pos.x - self.rush_role_end_dir.x * offset, self.attack_role_end_real_pos.y - self.rush_role_end_dir.y * offset) else self.rush_role_end_pos.x = self.attack_role_end_real_pos.x - self.rush_role_end_dir.x * offset self.rush_role_end_pos.y = self.attack_role_end_real_pos.y - self.rush_role_end_dir.y * offset end if self.scene_mgr:IsBlockXY(self.rush_role_end_pos.x / SceneObj_LogicRealRatio_x, self.rush_role_end_pos.y / SceneObj_LogicRealRatio_y) then self.rush_role_end_pos.x = role.real_pos.x self.rush_role_end_pos.y = role.real_pos.y end -- self.main_role:DoRush(self.rush_role_end_pos, Config.otherFightInfo.rush_to_monster_speed, use_skill_func) local rush_speed = Config.otherFightInfo.rush_to_monster_speed self.main_role:DoRush(self.rush_role_end_pos, rush_speed, use_skill_func) else use_skill_func() end end self.need_rush_to_role = false --保存选中对象 self:SetClickTarget(role) --在攻击前如果还没设置技能,就要先设置一个技能,以便进行攻击距离判断 if self.SkillMgr:getCurrentSkill() == nil or self.SkillMgr:IsThreeAttackSkill(skill_id) then self.SkillMgr:setCurrentSkillId(self.SkillMgr:getBaseSkill()) end local attack_range = self.SkillMgr:GetCurrentAttackRange() if attack_range < 50 then attack_range = 50 end local target_obj = role if self.attack_role_start_real_pos == nil then self.attack_role_start_real_pos = co_TableXY(self.main_role:GetRealPos()) else self.attack_role_start_real_pos.x = self.main_role.real_pos.x self.attack_role_start_real_pos.y = self.main_role.real_pos.y end if self.attack_role_end_real_pos == nil then self.attack_role_end_real_pos = co_TableXY(target_obj:GetRealPos()) else self.attack_role_end_real_pos.x = target_obj.real_pos.x self.attack_role_end_real_pos.y = target_obj.real_pos.y end if self.rush_role_end_dir == nil then self.rush_role_end_dir = co_TableXY(self.attack_role_end_real_pos.x-self.attack_role_start_real_pos.x, self.attack_role_end_real_pos.y-self.attack_role_start_real_pos.y) else self.rush_role_end_dir.x = self.attack_role_end_real_pos.x - self.attack_role_start_real_pos.x self.rush_role_end_dir.y = self.attack_role_end_real_pos.y - self.attack_role_start_real_pos.y end self.rush_role_distance = co_NormaliseXYTable(self.rush_role_end_dir) local max_rush_dis = Config.otherFightInfo.rush_to_monster_max_dis if self.rush_role_distance <= attack_range then --在最小范围内,直接放技能 self.need_rush_to_role = false if self.main_role:IsInState(PoseState.MOVE) then --转向目标,然后站立 self.main_role:SetDirection(self.attack_role_start_real_pos, self.attack_role_end_real_pos, true, true) self.main_role:DoStand() end if not self.SkillMgr:isInRigidity() then self.last_attack_time = Status.NowTime GlobalEventSystem:Fire(FightEvent.RELEASE_MAIN_SKILL, nil, nil, role.compress_id) end elseif self.rush_role_distance <= max_rush_dis then --在冲刺范围内,直接冲刺 self.need_rush_to_role = true self.last_find_target_time = Time.time rush_action_func() else --超过冲刺范围,先移动,再冲刺 self.need_rush_to_role = true self.last_find_target_time = Time.time OperateManager.Instance:StartTargetAction(role.compress_id, max_rush_dis, rush_action_func) end end --任务寻路,只有个坐标点,也要冲刺 function Scene:MainRoleRushToPos(mon_pos) if not mon_pos then return end self:CancelWaitQuest() if self.main_role and not self.main_role:CanMove() then local timer_func = function () if self.main_role and self.main_role:CanMove() then self:MainRoleRushToPos(mon_pos) return end end self.rush_to_pos_timer = GlobalTimerQuest:AddPeriodQuest(timer_func, 0.1, -1) return end --到目标点后放技能 local function use_skill_func() GlobalEventSystem:Fire(FightEvent.RELEASE_MAIN_SKILL) GlobalEventSystem:Fire(EventName.STARTAUTOFIGHT) end local function rush_action_func( ) if self.need_rush_to_pos then local offset = 250 if self.rush_end_real_pos == nil then self.rush_end_real_pos = co_TableXY(self.orign_rush_end_pos.x - self.rush_pos_end_dir.x * offset, self.orign_rush_end_pos.y - self.rush_pos_end_dir.y * offset) else self.rush_end_real_pos.x = self.orign_rush_end_pos.x - self.rush_pos_end_dir.x * offset self.rush_end_real_pos.y = self.orign_rush_end_pos.y - self.rush_pos_end_dir.y * offset end if self.scene_mgr:IsBlockXY(self.rush_end_real_pos.x / SceneObj_LogicRealRatio_x, self.rush_end_real_pos.y / SceneObj_LogicRealRatio_y) then self.rush_end_real_pos.x = self.orign_rush_end_pos.x self.rush_end_real_pos.y = self.orign_rush_end_pos.y end local rush_speed = Config.otherFightInfo.rush_to_monster_speed self.main_role:DoRush(self.rush_end_real_pos, rush_speed, use_skill_func) else GlobalEventSystem:Fire(FightEvent.RELEASE_MAIN_SKILL) GlobalEventSystem:Fire(EventName.STARTAUTOFIGHT) end end --是否需要冲刺 self.need_rush_to_pos = false local attack_range = 200 self.orign_rush_end_pos = mon_pos if self.rush_start_real_pos == nil then self.rush_start_real_pos = co_TableXY(self.main_role:GetRealPos()) else self.rush_start_real_pos.x = self.main_role.real_pos.x self.rush_start_real_pos.y = self.main_role.real_pos.y end if self.rush_pos_end_dir == nil then self.rush_pos_end_dir = co_TableXY(mon_pos.x-self.rush_start_real_pos.x, mon_pos.y-self.rush_start_real_pos.y) else self.rush_pos_end_dir.x = mon_pos.x - self.rush_start_real_pos.x self.rush_pos_end_dir.y = mon_pos.y - self.rush_start_real_pos.y end self.rush_pos_distance = co_NormaliseXYTable(self.rush_pos_end_dir) local max_rush_dis = Config.otherFightInfo.rush_to_monster_max_dis if self.rush_pos_distance <= attack_range then --在最小范围内,直接放技能 self.need_rush_to_pos = false if self.main_role:IsInState(PoseState.MOVE) then --转向目标,然后站立 self.main_role:SetDirection(self.attack_mon_start_real_pos, self.attack_mon_end_real_pos, true, true) self.main_role:DoStand() end use_skill_func() elseif self.rush_pos_distance <= max_rush_dis then --在冲刺范围内,直接冲刺 self.need_rush_to_pos = true self.last_find_target_time = Time.time rush_action_func() else --超过冲刺范围,先移动,再冲刺 self.need_rush_to_pos = true self.last_find_target_time = Time.time if not self.temp_logic_pos then self.temp_logic_pos = co_TableXY(mon_pos.x/SceneObj_LogicRealRatio_x, mon_pos.y/SceneObj_LogicRealRatio_y) end self.temp_logic_pos.x = mon_pos.x/SceneObj_LogicRealRatio_x self.temp_logic_pos.y = mon_pos.y/SceneObj_LogicRealRatio_y local range = 5 self:MainRoleMove(self.temp_logic_pos, range, rush_action_func) end end function Scene:GetSceneCenterPos() return self.mapView:GetSceneCenterPos() end function Scene:GetSceneSize() return self.mapView:GetMapSize() end function Scene:GetZoneHeight(logic_x,logic_y) local h = self.mapView:GetZoneHeight(logic_x,logic_y) if SceneManager.Instance:IsJumpOneScene() then h = h + JumpOneModel.SCENE_HEIGHT end return h end function Scene:GetMapResID(is_minimap) return self.mapView:GetResID(is_minimap) end function Scene:GetResIDByScene( scene_id, func ) self.mapView:GetResIDByScene(scene_id, func) end function Scene:SetDynamicArea(area_id,area_type) self.mapView:SetDynamicArea(area_id,area_type) end function Scene:SetMainRole(main_role) self.main_role = main_role end function Scene:GetMainRole() return self.main_role end function Scene:GetTileSize() return self.mapView:GetTileSize() end --[[ 把ObjType和ObjID压缩成一个64位ID,这是个“静态方法”,用Scene.CompressObjId的方式调用 @obj_type: SceneBaseType中定义的Obj类型 @obj_id: Obj的id,不同类型的Obj可能有相同的id @Return: 64位唯一ID ]] function Scene.CompressObjId(obj_type, obj_id) --lua 位操作不支持64位 所以改成另外一种方式 -- local t = bit.lshift(obj_type, 60) -- local val = bit.bor(t, obj_id or 0) -- return val return string.format("%d_%.0f",obj_type, obj_id) end function Scene.DecompressObjId(val) --lua 位操作不支持64位 所以改成另外一种方式 -- local obj_type = bit.rshift(val, 60) -- local obj_id = bit.band(val, 0x0fffffffffffffff) -- return obj_type, obj_id local list = Split(val,"_") return tonumber(list[1]),tonumber(list[2]) end function Scene:GetObjByCompressedId( compressed_id, can_get_dead_monster) if compressed_id == nil then return nil end local obj_type, obj_id = Scene.DecompressObjId(compressed_id) local obj = nil if obj_type == SceneBaseType.Role or obj_type == SceneBaseType.Fake_Role then obj = self:GetRole(obj_id) --主角 elseif obj_type == SceneBaseType.MainRole then obj = self.main_role --NPC elseif obj_type == SceneBaseType.Npc then obj = self:GetNpc(obj_id) -- --怪 elseif obj_type == SceneBaseType.Monster then obj = self:GetMonster(obj_id) if obj == nil and can_get_dead_monster then obj = self:GetMonsterDeadBody(obj_id) end elseif obj_type == SceneBaseType.Pokemon then obj = self:GetPokemon(obj_id) --协战宠物 objid不是角色id,是index elseif obj_type == SceneBaseType.AssisitPokemon then obj = self:GetAssisitPokemonById(RoleManager.Instance.mainRoleInfo.role_id,obj_id) -- --AI娘 elseif obj_type == SceneBaseType.Pet then obj = self:GetPet(obj_id) -- --其他 elseif obj_type == SceneBaseType.Other then obj = self:GetOther(obj_id) -- --传送门 elseif obj_type == SceneBaseType.Door then obj = self:GetDoor(obj_id) --掉落物 elseif obj_type == SceneBaseType.Drop then obj = self:GetDropItem(obj_id) --宝宝 elseif obj_type == SceneBaseType.Baby then obj = self:GetBaby(obj_id) --墓碑 elseif obj_type == SceneBaseType.Grave then obj = self:GetGraveItem(obj_id) elseif obj_type == SceneBaseType.HookRole then obj = self:GetHookRoleItem(obj_id) end return obj end function Scene:GetDoor(id) return self.door_list[cid] end function Scene:GetDropItem(id) return self.drop_list[id] end function Scene:GetNpcList( ) return self.npc_list end function Scene:GetNpc(id) local npc_obj = self.npc_list[tonumber(id)] if not npc_obj then local vo = self.scene_mgr:GetNpcVo(tonumber(id)) if vo then npc_obj = self.npc_pool:GetObjFreeList() if not npc_obj then npc_obj = Npc.New() end npc_obj:InitNpc(vo) self.npc_list[tonumber(id)] = npc_obj end end return npc_obj end function Scene:GetPartner( ins_id ) return self.partner_list[ins_id] end function Scene:GetSprite( ins_id ) return self.sprite_list[ins_id] end function Scene:GetPet( ins_id ) return self.pet_list[ins_id] end function Scene:GetPokemon(ins_id) return self.pokemon_list[ins_id] end function Scene:GetAssisitPokemon(ins_id,skill_id) local index = 0 if skill_id == 1210001 then index = 1 elseif skill_id == 1210002 then index = 2 elseif skill_id == 1210003 then index = 3 elseif skill_id == 1210004 then index = 4 elseif skill_id == 1210005 then index = 5 end if self.assisit_pokemon_list[ins_id] and self.assisit_pokemon_list[ins_id][index] then return self.assisit_pokemon_list[ins_id][index] end return nil end function Scene:GetAssisitPokemonById(ins_id,index) if self.assisit_pokemon_list[ins_id] and self.assisit_pokemon_list[ins_id][index] then return self.assisit_pokemon_list[ins_id][index] end return nil end function Scene:GetBaby( ins_id ) return self.baby_list[ins_id] end function Scene:GetMonster( ins_id ) return self.monster_list[ins_id] end function Scene:GetMonsterByTypeId(type_id) local monster_vo = self.scene_mgr:GetMonsterVoByTypeId(type_id) if monster_vo then return self:GetMonster(monster_vo.instance_id) end end --根据typeid获取到距离最近的monster function Scene:GetNearestMonsterByTypeId(type_id) local monster_vo_list = self.scene_mgr:GetAllMonsterVo() local mon_min_distance = 9999999--最短距离 local monster = nil local rx, ry = self:GetMainRole():GetRealPos() for k,v in pairs(monster_vo_list) do if v.type_id == type_id then local monster_temp = self:GetMonster(v.instance_id) if monster_temp then local dis = GameMath_GetDistance(monster_temp.vo.pos_x,monster_temp.vo.pos_y, rx, ry, false) if dis < mon_min_distance then mon_min_distance = dis monster = monster_temp end end end end return monster end --根据typeid获取到距离最近的monster(封印裂隙,本国团战用,找怪时忽略被被人采集中的怪) function Scene:GetNearestGuildCollectMonsterByTypeId(type_id) local monster_vo_list = self.scene_mgr:GetAllMonsterVo() local mon_min_distance = 9999999--最短距离 local monster = nil local rx, ry = self:GetMainRole():GetRealPos() for k,v in pairs(monster_vo_list) do if not type_id or v.type_id == type_id then local monster_temp = self:GetMonster(v.instance_id) if monster_temp and not GuildModel:getInstance():IsGuildIgnoreCollection(v.instance_id) and (type_id or not type_id and self:MonsterIsCollect(monster_temp.vo.type)) -- 没有传typeid的时候需要判断是否是采集物 then local pos = co.TableXY(monster_temp.vo.pos_x,monster_temp.vo.pos_y) local dis = GameMath_GetDistance(pos.x, pos.y, rx, ry, false) if dis < mon_min_distance then mon_min_distance = dis monster = monster_temp end end end end return monster end --获取随机一个不等于not_instance_id的怪物, 用于随机采集 function Scene:GetRandomMonsterByTypeId(type_id, not_instance_id) local monster_vo = self.scene_mgr:GetRandomMonsterVoByTypeId(type_id, not_instance_id) if monster_vo then return self:GetMonster(monster_vo.instance_id) end end function Scene:GetOther( ins_id ) return self.other_list[ins_id] end --获取除了角色以外的场景对象 function Scene:GetSceneObj(instance_id) local obj = self:GetMonster(instance_id) or self:GetPartner(instance_id) or self:GetOther(instance_id) or self:GetRole(instance_id) return obj end function Scene:GetMonsterList() return self.monster_list end function Scene:DetectFirstUnblockPoint(pos,dir,max_dist) return self.mapView:DetectFirstUnblockPoint(pos,dir,max_dist) end function Scene:FindWay(pos1,pos2,range) return self.mapView:FindWay(pos1,pos2,range) end function Scene:IsStraightLine(pos1,pos2) return self.mapView:IsStraightLine(pos1,pos2) end function Scene:DetectLastUnblockPoint(pos,dir,dist,jump_state) return self.mapView:DetectLastUnblockPoint(pos,dir,dist,jump_state) end --关闭场景雾效 function Scene:ChangeFogEnable(bool) local render = UnityEngine.RenderSettings if render then render.fog = bool end end function Scene:FindTargetDir(range, attacker, select_type, hiter_pos_type) attacker = attacker or self.main_role local range_pow = range and (range * range) or nil local mon_min_dist_tar = nil local mon_min_dist_pow = 100000000 local role_min_dist_tar = nil local role_min_dist_pow = 100000000 local x1, y1 = attacker:GetRealPos() local war_group1= attacker:GetVo().warGroup local special_mon_list = {} local at = attacker:GetType() if (at == SceneBaseType.FPearl or at == SceneBaseType.Pokemon or at == SceneBaseType.Baby) and attacker.owner then attacker = attacker.owner war_group1 = attacker:GetVo().warGroup end local function checkMonster() local mon_vo = nil for _, mon in pairs(self.monster_list) do --第一遍不包含特殊怪物时,特殊怪物就存到另外的表里 mon_vo = mon:GetVo() if mon_vo then local war_group2 = mon_vo.warGroup local diff_group = (war_group1 == 0 or war_group2 == 0 or war_group2 ~= war_group1) local hp_ok = (mon.vo and mon.vo.hp > 0) local x2, y2 = mon:GetRealPos() if hiter_pos_type == 1 then -- 腰部 y2 = y2 + mon:GetBodyHeight() * 0.5 elseif hiter_pos_type == 2 then y2 = y2 + mon:GetBodyHeight() end if not mon:IsDead() and hp_ok and diff_group and mon_vo.can_attack == 1 and mon_vo.guaji_flag == 0 and not mon.buff_manager:hasUnbeatableBuff() and mon_vo.type ~= MonsterType.COLLECT and mon_vo.type ~= MonsterType.UD_COLLECT and mon_vo.type ~= MonsterType.TASK_COLLECT and mon_vo.type ~= MonsterType.PICK and not mon:HasModelHideFlag(SceneObj.ModelHideFlag.ServerHide) then local dist_pow = GameMath_GetDistance(x1, y1, x2, y2, false) if range_pow == nil or range_pow >= dist_pow then if dist_pow < mon_min_dist_pow then mon_min_dist_pow = dist_pow mon_min_dist_tar = mon end end end end end return mon_min_dist_tar, mon_min_dist_pow end local function checkRole() if self.scene_mgr:IsPKScene() then for _, role in pairs(self.role_list) do local vo = role:GetVo() if vo then local war_group2 = vo.warGroup local same_group = war_group2 == war_group1 and war_group1 > 0 local canpkByPkStatus = true if select_type == 3 then--最近队友 辅助技能给自己队友加属性 if attacker_vo.team_id == vo.team_id and attacker_vo.team_id > 0 then same_group = false else same_group = true end elseif war_group1 == 0 and war_group2 == 0 then canpkByPkStatus = self.scene_mgr:CanPKByPKStatus(attacker.vo, vo) end local x2, y2 = role:GetRealPos() if hiter_pos_type == 1 then -- 腰部 y2 = y2 + role:GetBodyHeight() * 0.5 elseif hiter_pos_type == 2 then y2 = y2 + role:GetBodyHeight() end if role ~= attacker and canpkByPkStatus and not same_group and not role:IsDead() and not role.buff_manager:hasUnbeatableBuff() and role.id ~= attacker.id and not self.scene_mgr:IsSafeArea(nil, x2, y2) and not role:HasModelHideFlag(SceneObj.ModelHideFlag.ServerHide) then local dist_pow = GameMath_GetDistance(x1, y1, x2, y2, false) if range_pow == nil or range_pow >= dist_pow then if dist_pow < role_min_dist_pow then role_min_dist_pow = dist_pow role_min_dist_tar = role has_mon = true end end end end end end return role_min_dist_tar, role_min_dist_pow end local target_priority = lua_settingM:GetTargetPriority() if target_priority == 2 then local mon_tar, mon_dist = checkMonster() if mon_tar then return mon_tar else local role_tar, role_dist = checkRole() if role_tar then return role_tar end end elseif target_priority == 3 then local role_tar, role_dist = checkRole() if role_tar then return role_tar else local mon_tar, mon_dist = checkMonster() if mon_tar then return mon_tar end end else local mon_tar, mon_dist = checkMonster() local role_tar, role_dist = checkRole() local min_tar = nil local min_dist = 100000000 if mon_dist < min_dist then min_dist = mon_dist min_tar = mon_tar end if role_dist < min_dist then min_dist = role_dist min_tar = role_tar end if min_tar then return min_tar end end end --[[ @param dis:寻找距离多少像素之内的掉落, dis可为空 ]] function Scene:FindDropItem(dis, is_evil) if TableSize(self.drop_list) == 0 then return nil end local ret = {} local x1, y1 if is_evil and self.main_role and self.main_role.evil then x1, y1 = self.main_role.evil:GetRealPos() else x1, y1 = self.main_role:GetRealPos() end for k,drop_obj in pairs(self.drop_list) do local x2, y2 = drop_obj:GetRealPos() if drop_obj:IsCanPickUp() and not drop_obj:IsPicking() then local dist_pw = GameMath_GetDistance(x1, y1, x2, y2, false) if dis then if dist_pw < dis*dis then table_insert(ret,{drop_obj,dist_pw}) end else table_insert(ret,{drop_obj,dist_pw}) end end end if #ret > 0 then local sort_func = function(t1, t2) return t1[2] < t2[2] end table_sort(ret, sort_func) end return ret[1] end function Scene:FindEvilNearbyDropItem(dis) if TableSize(self.drop_list) == 0 then return nil end -- local ret = {} local x1, y1 = self.main_role.evil:GetRealPos() local min_dist,drop_vo = -1,nil for k,drop_obj in pairs(self.drop_list) do local x2, y2 = drop_obj:GetRealPos() if drop_obj:IsCanPickUp() and not drop_obj:IsPicking() then local dist_pw = GameMath_GetDistance(x1, y1, x2, y2, false) if dis then if dist_pw < dis*dis then if min_dist == -1 or dist_pw < min_dist then drop_vo = drop_obj end -- table_insert(ret,{drop_obj,dist_pw}) end else if min_dist == -1 or dist_pw < min_dist then drop_vo = drop_obj end --table_insert(ret,{drop_obj,dist_pw}) end end end -- if #ret > 0 then -- local sort_func = function(t1, t2) -- return t1[2] < t2[2] -- end -- table_sort(ret, sort_func) -- end return drop_vo end --[[ @param dis:寻找距离多少像素之内的掉落列表, dis可为空 boss_type: 找不等于该boss_type的掉落,可为空 ]] function Scene:FindDropList(dis, boss_type) if TableSize(self.drop_list) == 0 then return nil end local ret = {} local x1, y1 = self.main_role:GetRealPos() for k,drop_obj in pairs(self.drop_list) do local x2, y2 = drop_obj:GetRealPos() if drop_obj:IsCanPickUp() and (not boss_type or drop_obj.vo.boss_type~=boss_type) then local dist_pw = GameMath_GetDistance(x1, y1, x2, y2, false) if dis then if dist_pw < dis*dis then table_insert(ret,{drop_obj,dist_pw}) end else table_insert(ret,{drop_obj,dist_pw}) end end end if #ret > 0 then local sort_func = function(t1, t2) return t1[2] < t2[2] end table_sort(ret, sort_func) end return ret end --总的选择目标方法 function Scene:FindTargets(find_type, find_number, distance, area, find_dir, find_radian, center_pos, attacker, movie_cfg, select_type, defender_max_attack_count, not_use_3d_select_mode, hiter_pos_type, is_auto_select, find_way,contain_collect_type) if Scene.FIND_TARGET_TYPE.monster == find_type then local monster_list,left_num = self:FindMonsters(find_number, distance, area, find_dir, find_radian, center_pos, attacker, movie_cfg, select_type, defender_max_attack_count, not_use_3d_select_mode, hiter_pos_type, is_auto_select, find_way,contain_collect_type) return monster_list, {} elseif Scene.FIND_TARGET_TYPE.role == find_type then local role_list,left_num = self:FindRoles(find_number, distance, area, find_dir, find_radian, center_pos, attacker, movie_cfg, select_type, defender_max_attack_count, not_use_3d_select_mode, hiter_pos_type, is_auto_select) return role_list, {} elseif Scene.FIND_TARGET_TYPE.all == find_type then local role_list,monster_list,left_num = nil monster_list,left_num = self:FindMonsters(find_number, distance, area, find_dir, find_radian, center_pos, attacker, movie_cfg, select_type, defender_max_attack_count, not_use_3d_select_mode, hiter_pos_type, is_auto_select, find_way,contain_collect_type) role_list,left_num = self:FindRoles(left_num, distance, area, find_dir, find_radian, center_pos, attacker, movie_cfg, select_type, defender_max_attack_count, not_use_3d_select_mode, hiter_pos_type, is_auto_select) return monster_list, role_list end end --总的选择目标方法 function Scene:FindSkillTargets(find_type, find_role_number, find_monster_num, distance, area, find_dir, find_radian, center_pos, attacker, movie_cfg, select_type, defender_max_attack_count, not_use_3d_select_mode, hiter_pos_type, is_auto_select) if Scene.FIND_TARGET_TYPE.monster == find_type then local monster_list,left_num = self:FindMonsters(find_monster_num, distance, area, find_dir, find_radian, center_pos, attacker, movie_cfg, select_type, defender_max_attack_count, not_use_3d_select_mode, hiter_pos_type, is_auto_select) return monster_list, left_num elseif Scene.FIND_TARGET_TYPE.role == find_type then local role_list,left_num = self:FindRoles(find_role_number, distance, area, find_dir, find_radian, center_pos, attacker, movie_cfg, select_type, defender_max_attack_count, not_use_3d_select_mode, hiter_pos_type, is_auto_select) return role_list, left_num elseif Scene.FIND_TARGET_TYPE.all == find_type then local role_list,monster_list, left_num = nil monster_list,left_num = self:FindMonsters(find_monster_num, distance, area, find_dir, find_radian, center_pos, attacker, movie_cfg, select_type, defender_max_attack_count, not_use_3d_select_mode, hiter_pos_type, is_auto_select) role_list,left_num = self:FindRoles(find_role_number, distance, area, find_dir, find_radian, center_pos, attacker, movie_cfg, select_type, defender_max_attack_count, not_use_3d_select_mode, hiter_pos_type, is_auto_select) return monster_list, role_list end end --根据条件检索出符合条件的怪物列表 --@n: 怪物数量,默认为1 --@distance: 检索距离 用于直线表示直线的长度 --@area: 检索范围半径,默认为无限,即全图范围 --@find_dir: 检索方向 --@find_radian: 检索角度 用于扇形 --@center_pos: 检索范围的中心坐标点,默认为主角坐标 --@find_way == : 寻找目标的方式,1:目标的类型(采集>boss>小怪) 2:血量 --@contain_collect_type == :包含采集类型 function Scene:FindMonsters(n, distance, area, find_dir, find_radian, center_pos, attacker, movie_cfg, select_type, defender_max_attack_count, not_use_3d_select_mode, hiter_pos_type, is_auto_select, find_way,contain_collect_type) if n == 0 then return {}, 0 end attacker = attacker or self.main_role find_way = find_way or 1 contain_collect_type = contain_collect_type == nil and true or contain_collect_type local area_pw = area and (area * area) or nil local war_group1= attacker:GetVo().warGroup local my_dir = find_dir or attacker:GetDirection() if my_dir then my_dir:normalise() end local dot_min = find_radian and math.cos(find_radian / 2) or nil --左右各一半角度的cos值(dot值) local x1, y1 = attacker:GetRealPos() if center_pos ~= nil then x1, y1 = center_pos.x, center_pos.y end if (attacker:GetType() == SceneBaseType.FPearl or attacker:GetType() == SceneBaseType.Pokemon or attacker:GetType() == SceneBaseType.Baby) and attacker.owner then attacker = attacker.owner war_group1= attacker:GetVo().warGroup end local ret = {} --把所有在距离内的、角度范围内的怪物找出来 local vo = nil local at = nil local war_group2 = nil local same_group = nil local x2, y2 = nil local sort_type = 0 local canSelected = true for _, monster in pairs(self.monster_list) do vo = monster:GetVo() if vo then at = attacker:GetType() war_group2 = vo.warGroup same_group = (at == SceneBaseType.Monster and war_group2 == war_group1) or ((at == SceneBaseType.Role or at == SceneBaseType.MainRole) and war_group2 == war_group1 and war_group1 > 0) x2, y2 = monster:GetRealPos() sort_type = 0 if find_way == 1 then if vo.type == MonsterType.TASK_COLLECT or vo.type == MonsterType.COLLECT or vo.type == MonsterType.UD_COLLECT then sort_type = 999 elseif vo.boss_type > 0 then sort_type = 899 + vo.boss_type else sort_type = 799 end elseif find_way == 2 then sort_type = 999 + vo.hp/vo.maxHp end if monster ~= attacker and not same_group and not monster:IsDead() and vo.guaji_flag == 0 and (vo.can_attack == 1 or vo.type == MonsterType.MISSION_COLLECT) and not monster.buff_manager:hasUnbeatableBuff() and vo.type ~= MonsterType.PICK and (vo.type ~= MonsterType.COLLECT or (contain_collect_type and vo.type == MonsterType.COLLECT)) and (not is_auto_select or not monster:HasModelHideFlag(SceneObj.ModelHideFlag.ServerHide)) then --计算距离(因为结果要按距离排序,所以必须要算) if hiter_pos_type == 1 then -- 腰部 y2 = y2 + monster:GetBodyHeight() * 0.5 elseif hiter_pos_type == 2 then y2 = y2 + monster:GetBodyHeight() end canSelected = true if movie_cfg and movie_cfg.unselected_by_block then local start_logic_pos = Vector2(attacker.real_pos.x / SceneObj_LogicRealRatio_x, attacker.real_pos.y / SceneObj_LogicRealRatio_y) local end_logic_pos = Vector2(x2 / SceneObj_LogicRealRatio_x, y2 / SceneObj_LogicRealRatio_y) if not self:IsStraightLine(start_logic_pos, end_logic_pos) then canSelected = false end end if canSelected then local dist_pw = GameMath_GetDistance(x1, y1, x2, y2, false) if dist_pw <= 2500 then --如果距离在(50,50)之内,就忽略距离判断和角度判断 table_insert(ret, {monster, dist_pw,sort_type}) --进行角度范围判定 攻击距离为半径,攻击范围为角度的扇形 elseif dot_min ~= nil then local dir = co.TempVector2(x2-x1, y2-y1) dir:normalise() local dot = my_dir:dotProduct(dir) --a·b=|a||b|·cosθ if dot >= dot_min then if dist_pw <= distance * distance then table_insert(ret, {monster, dist_pw,sort_type}) end end dir:DeleteV() --进行直线范围判定(要算dot值判断是否在前方) 攻击距离为长,攻击范围为宽的长方形 elseif distance and area then if dist_pw <= (distance + area) * (distance + area) then local dir = co.TempVector2(x2-x1, y2-y1) dir:normalise() local dot = my_dir:dotProduct(dir) if dot > 0 then --在前方再详细算距离 local relate_pos = {x=x2-x1, y=y2-y1} local d = GameMath.DistancePointToLine(my_dir, relate_pos, false) local curr_area = area --椭圆处理 curr_area = curr_area if d <= curr_area * curr_area then table_insert(ret, {monster, dist_pw, sort_type}) end end dir:DeleteV() end elseif area_pw == nil or dist_pw <= area_pw then --圆形 table_insert(ret, {monster, dist_pw, sort_type}) end end end end end local res = {} local left_num = n if #ret > 0 then if #ret > 1 then --对所有范围内的怪物按距离排序,先按(采集怪,boss怪,精英怪,普通怪)的怪物类型排序,如果类型相同,按距离排序 local sort_func = function(t1, t2) if t1[3] == t2[3] then return t1[2] < t2[2] else return t1[3] > t2[3] end end table_sort(ret, sort_func) end for i = 1, n do local t = ret[i] if t then table_insert(res, t[1]) left_num = left_num - 1 end end end return res,left_num end --根据条件检索出符合条件的怪物列表 --@n: 怪物数量,默认为1 --@distance: 检索距离 用于直线表示直线的长度 --@area: 检索范围半径,默认为无限,即全图范围 --@find_dir: 检索方向 --@find_radian: 检索角度 用于扇形 --@center_pos: 检索范围的中心坐标点,默认为主角坐标 function Scene:FindPartners(n, distance, area, find_dir, find_radian, center_pos, attacker, movie_cfg, select_type, defender_max_attack_count,not_use_3d_select_mode, hiter_pos_type, is_auto_select) if not self.scene_mgr:IsPKScene() then return {}, n end if n == 0 then return {}, 0 end attacker = attacker or self.main_role local area_pw = area and (area * area) or nil local war_group1= attacker:GetVo().warGroup local my_dir = find_dir or attacker:GetDirection() if my_dir then my_dir:normalise() end local dot_min = find_radian and math.cos(find_radian / 2) or nil --左右各一半角度的cos值(dot值) local x1, y1 = attacker:GetRealPos() if center_pos ~= nil then x1, y1 = center_pos.x, center_pos.y end local ret = {} --把所有在距离内的、角度范围内的伙伴找出来 for _, partner in pairs(self.partner_list) do --只找可以挂机的怪 local at = attacker:GetType() local war_group2 = partner:GetVo().warGroup local same_group = war_group2 == war_group1 and war_group1 > 0 local vo = partner:GetVo() local hited_count_by_mainRole = 0 if attacker == self.main_role and defender_max_attack_count then local defender_count_info = SceneManager.Instance.mainRole_attacker_list[partner.id] if defender_count_info then if defender_max_attack_count > defender_count_info.attack_count then hited_count_by_mainRole = defender_count_info.attack_count else hited_count_by_mainRole = nil end end end if partner ~= attacker and not same_group and not partner:IsDead() and not partner.buff_manager:hasUnbeatableBuff() and hited_count_by_mainRole then --计算距离(因为结果要按距离排序,所以必须要算) local x2, y2 = partner:GetRealPos() local canSelected = true if movie_cfg and movie_cfg.unselected_by_block then local start_logic_pos = Vector2(attacker.real_pos.x / SceneObj_LogicRealRatio_x, attacker.real_pos.y / SceneObj_LogicRealRatio_y) local end_logic_pos = Vector2(x2 / SceneObj_LogicRealRatio_x, y2 / SceneObj_LogicRealRatio_y) if not self:IsStraightLine(start_logic_pos, end_logic_pos) then canSelected = false end end if canSelected then local dist_pw = GameMath_GetDistance(x1, y1, x2, y2, false) if dist_pw <= 2500 then --如果距离在(50,50)之内,就忽略距离判断和角度判断 table_insert(ret, {partner, dist_pw, hited_count_by_mainRole}) --进行角度范围判定 攻击距离为半径,攻击范围为角度的扇形 elseif dot_min ~= nil then local dir = co.Vector2(x2-x1, y2-y1) dir:normalise() local dot = my_dir:dotProduct(dir) --a·b=|a||b|·cosθ if dot >= dot_min then if dist_pw <= distance * distance then table_insert(ret, {partner, dist_pw, hited_count_by_mainRole}) end end --进行直线范围判定(要算dot值判断是否在前方) 攻击距离为长,攻击范围为宽的长方形 elseif distance and area then if dist_pw <= (distance * distance) then local dir = co.Vector2(x2-x1, y2-y1) dir:normalise() local dot = my_dir:dotProduct(dir) if dot > 0 then --在前方再详细算距离 local relate_pos = {x=x2-x1, y=y2-y1} local d = GameMath.DistancePointToLine(my_dir, relate_pos, false) local curr_area = area * 0.5 if d <= curr_area * curr_area then table_insert(ret, {partner, dist_pw, hited_count_by_mainRole}) end end end elseif area_pw == nil or dist_pw <= area_pw then table_insert(ret, {partner, dist_pw, hited_count_by_mainRole}) end end end end if #ret > 1 then --对所有范围内的伙伴按距离排序 local sort_func = function(t1, t2) if attacker == self.main_role and defender_max_attack_count then if t1[3] == t2[3] then return t1[2] < t2[2] else return t1[3] < t2[3] end else return t1[2] < t2[2] end end table_sort(ret, sort_func) end local res = {} local left_num = n for i=1, n do local t = ret[i] if t == nil then break else table_insert(res, t[1]) left_num = left_num - 1 end end return res, left_num end --根据条件检索出符合条件的玩家列表 --@n: 玩家数量,默认为1 --@distance: 检索距离 用于直线表示直线的长度 --@area: 检索范围半径,默认为无限,即全图范围 --@find_dir: 检索方向 --@find_radian: 检索角度 用于扇形 --@center_pos: 检索范围的中心坐标点,默认为主角坐标 --@movie_cfg 客户端技能配置 --@select_type 目标选取类型 3最近队友 function Scene:FindRoles(n, distance, area, find_dir, find_radian, center_pos, attacker, movie_cfg, select_type, defender_max_attack_count, not_use_3d_select_mode, hiter_pos_type, is_auto_select) if not self.scene_mgr:IsPKScene() then return {}, n end if n == 0 then return {}, 0 end attacker = attacker or self.main_role local attacker_vo = attacker:GetVo() local area_pw = area and (area * area) or nil local my_dir = find_dir or attacker:GetDirection() if my_dir then my_dir:normalise() end local dot_min = find_radian and math.cos(find_radian / 2) or nil --左右各一半角度的cos值(dot值) local war_group1= attacker_vo.warGroup local x1, y1 = attacker:GetRealPos() if center_pos ~= nil then x1, y1 = center_pos.x, center_pos.y end if (attacker:GetType() == SceneBaseType.FPearl or attacker:GetType() == SceneBaseType.Pokemon or attacker:GetType() == SceneBaseType.Baby) and attacker.owner then attacker = attacker.owner war_group1 = attacker:GetVo().warGroup end local ret = {} local vo = nil local war_group2 = nil local same_group = nil local canpkByPkStatus = true local x2, y2 = nil local canSelected = true for _, role in pairs(self.role_list) do vo = role:GetVo() if vo and role.id ~= attacker.id then war_group2 = vo.warGroup same_group = war_group2 == war_group1 and war_group1 > 0 canpkByPkStatus = true if select_type == 3 then--最近队友 辅助技能给自己队友加属性 if attacker_vo.team_id == vo.team_id and attacker_vo.team_id > 0 then same_group = false else same_group = true end elseif war_group1 == 0 and war_group2 == 0 then if attacker:GetType() == SceneBaseType.Pokemon or attacker:GetType() == SceneBaseType.Baby or attacker:GetType() == SceneBaseType.FPearl then if attacker.owner and attacker.owner.vo then canpkByPkStatus = self.scene_mgr:CanPKByPKStatus(attacker.owner.vo, vo) else canpkByPkStatus = false end else canpkByPkStatus = self.scene_mgr:CanPKByPKStatus(attacker.vo, vo) end end canpkByPkStatus = canpkByPkStatus --or self.fight_back_mgr:IsAttacker(vo.role_id) x2, y2 = role:GetRealPos() if role ~= attacker and canpkByPkStatus and not same_group and not role:IsDead() and not role.buff_manager:hasUnbeatableBuff() and not vo.is_virtual_friend and (vo.protect_time - TimeUtil:getServerTime() <= 0) and (not is_auto_select or ( (self.scene_mgr:IsGuildWarScene() or not self.scene_mgr:IsSafeArea(nil, x2, y2)) and not role:HasModelHideFlag(SceneObj.ModelHideFlag.ServerHide))) and (attacker:GetType() ~= SceneBaseType.FPearl and attacker:GetType() ~= SceneBaseType.Pokemon and attacker:GetType() ~= SceneBaseType.Baby or (attacker.owner and attacker.owner ~= role)) then if hiter_pos_type == 1 then -- 腰部 y2 = y2 + role:GetBodyHeight() * 0.5 elseif hiter_pos_type == 2 then y2 = y2 + role:GetBodyHeight() end canSelected = true if movie_cfg and movie_cfg.unselected_by_block then local start_logic_pos = Vector2(attacker.real_pos.x / SceneObj_LogicRealRatio_x, attacker.real_pos.y / SceneObj_LogicRealRatio_y) local end_logic_pos = Vector2(x2 / SceneObj_LogicRealRatio_x, y2 / SceneObj_LogicRealRatio_y) if not self:IsStraightLine(start_logic_pos, end_logic_pos) then canSelected = false end end if canSelected then --计算距离(因为结果要按距离排序,所以必须要算) local dist_pw = GameMath_GetDistance(x1, y1, x2, y2, false) if dist_pw <= 2500 then --如果距离在(50,50)之内,就忽略距离判断和角度判断 table_insert(ret, {role, dist_pw}) --进行角度范围判定 攻击距离为半径,攻击范围为角度的扇形 elseif dot_min ~= nil then local dir = co.Vector2(x2-x1, y2-y1) dir:normalise() local dot = my_dir:dotProduct(dir) --a·b=|a||b|·cosθ if dot >= dot_min then if dist_pw <= distance * distance then table_insert(ret, {role, dist_pw}) end end --进行直线范围判定(要算dot值判断是否在前方) 攻击距离为长,攻击范围为宽的长方形 elseif distance and area then if dist_pw <= (distance * distance) then local dir = co.Vector2(x2-x1, y2-y1) dir:normalise() local dot = my_dir:dotProduct(dir) if dot > 0 then --在前方再详细算距离 local relate_pos = {x=x2-x1, y=y2-y1} local d = GameMath.DistancePointToLine(my_dir, relate_pos, false) local curr_area = area * 0.5 if d <= curr_area * curr_area then table_insert(ret, {role, dist_pw}) end end end elseif area_pw == nil or dist_pw <= area_pw then table_insert(ret, {role, dist_pw}) end end end end end local res = {} local left_num = n if #ret > 0 then --超过一个才需要排序 if #ret > 1 then --对所有范围内的怪物按距离排序 local sort_func = function(t1, t2) return t1[2] < t2[2] end table_sort(ret, sort_func) end for i=1, n do local t = ret[i] if t then table_insert(res, t[1]) left_num = left_num - 1 end end end return res,left_num end --挂机玩家寻找怪物方法 --根据条件检索出符合条件的怪物列表 --@n: 怪物数量,默认为1 --@distance: 检索距离 用于直线表示直线的长度 --@area: 检索范围半径,默认为无限,即全图范围 --@find_dir: 检索方向 --@find_radian: 检索角度 用于扇形 --@center_pos: 检索范围的中心坐标点,默认为主角坐标 --@find_way == : 寻找目标的方式,1:目标的类型(采集>boss>小怪) 2:血量 function Scene:HookRoleFindMonsters(n, distance, area, find_dir, find_radian, center_pos, attacker, movie_cfg, select_type, defender_max_attack_count, not_use_3d_select_mode, hiter_pos_type, is_auto_select, find_way) if self.scene_mgr:IsSafeScene() then return {}, n end if n == 0 then return {}, 0 end attacker = attacker or self.main_role find_way = find_way or 1 local area_pw = area and (area * area) or nil local war_group1= attacker:GetVo().warGroup local my_dir = find_dir or attacker:GetDirection() if my_dir then my_dir:normalise() end local dot_min = find_radian and math.cos(find_radian / 2) or nil --左右各一半角度的cos值(dot值) local x1, y1 = attacker:GetRealPos() if center_pos ~= nil then x1, y1 = center_pos.x, center_pos.y end local ret = {} --把所有在距离内的、角度范围内的怪物找出来 local vo = nil local at = nil local x2, y2 = nil local sort_type = 0 local canSelected = true for _, monster in pairs(self.monster_list) do vo = monster:GetVo() if vo then at = attacker:GetType() x2, y2 = monster:GetRealPos() sort_type = 0 if find_way == 1 then sort_type = 799 elseif find_way == 2 then sort_type = 999 + vo.hp/vo.maxHp end if monster ~= attacker and not monster:IsDead() and vo.guaji_flag == 0 and vo.can_attack == 1 and not monster.buff_manager:hasUnbeatableBuff() and vo.type == MonsterType.NORMAL and (not is_auto_select or not monster:HasModelHideFlag(SceneObj.ModelHideFlag.ServerHide)) then --计算距离(因为结果要按距离排序,所以必须要算) if hiter_pos_type == 1 then -- 腰部 y2 = y2 + monster:GetBodyHeight() * 0.5 elseif hiter_pos_type == 2 then y2 = y2 + monster:GetBodyHeight() end canSelected = true if movie_cfg and movie_cfg.unselected_by_block then local start_logic_pos = Vector2(attacker.real_pos.x / SceneObj_LogicRealRatio_x, attacker.real_pos.y / SceneObj_LogicRealRatio_y) local end_logic_pos = Vector2(x2 / SceneObj_LogicRealRatio_x, y2 / SceneObj_LogicRealRatio_y) if not self:IsStraightLine(start_logic_pos, end_logic_pos) then canSelected = false end end if canSelected then local dist_pw = GameMath_GetDistance(x1, y1, x2, y2, false) if dist_pw <= 2500 then --如果距离在(50,50)之内,就忽略距离判断和角度判断 table_insert(ret, {monster, dist_pw,sort_type}) --进行角度范围判定 攻击距离为半径,攻击范围为角度的扇形 elseif dot_min ~= nil then local dir = co.Vector2(x2-x1, y2-y1) dir:normalise() local dot = my_dir:dotProduct(dir) --a·b=|a||b|·cosθ if dot >= dot_min then if dist_pw <= distance * distance then table_insert(ret, {monster, dist_pw,sort_type}) end end --进行直线范围判定(要算dot值判断是否在前方) 攻击距离为长,攻击范围为宽的长方形 elseif distance and area then if dist_pw <= (distance + area) * (distance + area) then local dir = co.Vector2(x2-x1, y2-y1) dir:normalise() local dot = my_dir:dotProduct(dir) if dot > 0 then --在前方再详细算距离 local relate_pos = {x=x2-x1, y=y2-y1} local d = GameMath.DistancePointToLine(my_dir, relate_pos, false) local curr_area = area if d <= curr_area * curr_area then table_insert(ret, {monster, dist_pw, sort_type}) end end end elseif area_pw == nil or dist_pw <= area_pw then --圆形 table_insert(ret, {monster, dist_pw, sort_type}) end end end end end local res = {} local left_num = n if #ret > 0 then --对所有范围内的怪物按距离排序,先按(采集怪,boss怪,精英怪,普通怪)的怪物类型排序,如果类型相同,按距离排序 local sort_func = function(t1, t2) if t1[3] == t2[3] then return t1[2] < t2[2] else return t1[3] > t2[3] end end table_sort(ret, sort_func) for i = 1, n do local t = ret[i] if t then table_insert(res, t[1]) left_num = left_num - 1 end end end return res,left_num end -- 取消寻路处理 function Scene:ClearFindWayParam() self:clearFindNextScene() end function Scene:ClearFindNextScene() self.scene_mgr.find_nextvo = nil self.find_isAgain = nil self.scene_mgr.next_scene_id=0 end function Scene:CancelWaitQuest( ) if self.timer then GlobalTimerQuest:CancelQuest(self.timer) self.timer = nil end if self.rush_to_pos_timer then GlobalTimerQuest:CancelQuest(self.rush_to_pos_timer) self.rush_to_pos_timer = nil end end function Scene:FindElement(findVo, isAgain) if not self.main_role then GameError.Instance:SendErrorToPHP("FindElement scene_data_loaded"..(self.scene_data_loaded and "yes" or "no") .." "..debug.traceback()) return end if self.main_role:IsFishingState() then Message.show("钓鱼中~,请先退出钓鱼状态") return end isAgain = isAgain or false if findVo == nil or findVo.type==nil or findVo.sceneId==nil or findVo.id==nil then return end -- 判断目标场景是否开启 if findVo.sceneId ~= self.scene_mgr:GetSceneId() then local vo = {} vo.scene_id = findVo.sceneId local hasOpen = MapModel:getInstance():CanEnterScene(vo) if hasOpen ~= true then Message.show("无法进入目标场景") logWarn("目标场景尚未开放 场景id" .. findVo.sceneId) return end end self:clearGoToData() GlobalEventSystem:Fire(EventName.FINDWAY_STARTED) -- 寻路NPC要重新计算距离 if findVo.type == FindVo.NPC then local npc = self.scene_mgr:GetNpcVo(findVo.id) if npc then findVo.x = npc.logic_x findVo.y = npc.logic_y end end TaskModel:getInstance().need_check_monster = findVo.need_check_monster --跳完后 继续寻路 OperateManager.Instance.jump_end_not_continue = false -----------------设置飞鞋坐标----------------- local function callback() GlobalEventSystem:Fire(EventName.FIND,findVo) end AutoFightManager:getInstance():SetFlyData(findVo.sceneId, findVo.x* SceneObj_LogicRealRatio_x, findVo.y* SceneObj_LogicRealRatio_y, callback) -----------------是否处于处于CanMove状态------------------ self:CancelWaitQuest() if self.main_role and not self.main_role:CanMove() and not self.main_role:IsInState(PoseState.STORY) then local timer_func = function () if self.main_role and self.main_role:CanMove() then self:FindElement(findVo) return end end self.timer = GlobalTimerQuest:AddPeriodQuest(timer_func, 0.1, -1) return end self.find_vo_cache = findVo local myx = self.mainrole_vo.pos_x / SceneObj_LogicRealRatio_x local myy = self.mainrole_vo.pos_y / SceneObj_LogicRealRatio_y --寻路自动上坐骑 local limit_dis = Config.otherFightInfo.ride_horse_limit_distance / SceneObj_LogicRealRatio_x if SceneManager.Instance:IsShowHorseScene() then if findVo.sceneId == self.scene_mgr:GetSceneId() then local distance_match = GameMath_GetDistance(myx, myy, findVo.x, findVo.y, false) > limit_dis*limit_dis local ride_is_unlock = TaskModel:getInstance():IsTaskFinished(10200) local pre_task_match = TaskModel:getInstance():IsTaskFinished(10310) local next_task_match = TaskModel:getInstance():IsTaskFinished(10430) --新手10310到10430任务期间不要自动上坐骑 if distance_match and ride_is_unlock and not (pre_task_match and not next_task_match) then GlobalEventSystem:Fire(EventName.RIDE_HORSE) end else if not findVo.force_change_scene then GlobalEventSystem:Fire(EventName.RIDE_HORSE) end end end if findVo.sceneId ~= self.scene_mgr:GetSceneId() then --跨场景 local door_list = self.scene_mgr.door_vo_list local temp_door = false local min_door_dis_pow = 0 for k,v in pairs(door_list) do local x1, y1 = v.pixel_x, v.pixel_y local x2, y2 = self.main_role:GetRealPos() local dist_pow = GameMath_GetDistance(x1, y1, x2, y2, false) if not temp_door or dist_pow < min_door_dis_pow then temp_door = v min_door_dis_pow = dist_pow end end if temp_door then self:MainRoleMoveToDoor(temp_door) else findVo.force_change_scene = false self.scene_mgr.find_nextvo = findVo self.find_isAgain = isAgain GlobalEventSystem:Fire(SceneEventType.REQUEST_CHANGE_SCENE, findVo.sceneId, findVo.call_type) end return end if findVo.type == FindVo.SCENE then self:ClearFindNextScene() GlobalEventSystem:Fire(EventName.FINDWAY_ENDED) return elseif findVo.type == FindVo.NPC then if not SceneManager.Instance:IsHomeBuildScene() then self:mainRoleToNpc(findVo.id) else local lx, ly = self.main_role:GetLogicPos() if GameMath_GetDistance(lx, ly, findVo.x, findVo.y) <= 1 then self.main_role:DoStand() local onDelay = function () if self.delay_timer_id then GlobalTimerQuest:CancelQuest(self.delay_timer_id) self.delay_timer_id = nil end GlobalEventSystem:Fire(EventName.FINDWAY_ENDED) end self.delay_timer_id = GlobalTimerQuest:AddDelayQuest(onDelay, 0.5) if findVo.call_back then findVo.call_back() end else self:MainRoleMoveAndCancel(co.TableXY(findVo.x, findVo.y), 0, findVo.call_back) end end elseif findVo.type == FindVo.MONSTER then --主要采集任务 local lx, ly = self.main_role:GetLogicPos() if (findVo.x > 0 or findVo.y > 0) and GameMath_GetDistance(lx, ly, findVo.x, findVo.y) > 20 then if isAgain == false then local function findAgain() local mon = self:FindNearestMonster(findVo.id, false, true) if mon then self:MainRoleAttackMonster(mon) end end self:MainRoleMoveAndCancel(co.TableXY(findVo.x, findVo.y), 0, findAgain) end elseif self.scene_mgr:GetMonsterVoByTypeId(findVo.id) ~= nil then if isAgain == false then local mon = self:FindNearestMonster(findVo.id, false, true) if mon then self:MainRoleAttackMonster(mon) GlobalEventSystem:Fire(EventName.FINDWAY_ENDED) end end else GlobalEventSystem:Fire(EventName.FINDWAY_ENDED) if TaskModel:getInstance().is_auto_task and not AutoFightManager:getInstance().is_temp_mode then --九宫格加载慢,隔1秒去尝试找怪 local onDelay = function ( ) if self.scene_mgr:IsMainCityAndFieldScene() then GlobalEventSystem:Fire(EventName.FORCE_TO_DO_TASK) end end setTimeout(onDelay, 1) end end elseif findVo.type == FindVo.PLAYER then local player = self:GetRole(findVo.id) GlobalEventSystem:Fire(EventName.FINDWAY_ENDED) if player ~= nil then self:MainRoleAttackRole(player) end elseif findVo.type == FindVo.POINT then --主要打怪任务 local lx, ly = self.main_role:GetLogicPos() local range = findVo.range or 0 if GameMath_GetDistance(lx, ly, findVo.x, findVo.y) <= 1 then GlobalEventSystem:Fire(EventName.FINDWAY_ENDED) if findVo.call_back then findVo.call_back() end else self:MainRoleMoveAndCancel(co.TableXY(findVo.x, findVo.y), range, findVo.call_back) end elseif findVo.type == FindVo.Fishing then local lx, ly = self.main_role:GetLogicPos() if GameMath_GetDistance(lx, ly, findVo.x, findVo.y) <= 1 then self.main_role:DoStand() local onDelay = function () if self.delay_timer_id then GlobalTimerQuest:CancelQuest(self.delay_timer_id) self.delay_timer_id = nil end GlobalEventSystem:Fire(EventName.FINDWAY_ENDED) end self.delay_timer_id = GlobalTimerQuest:AddDelayQuest(onDelay, 0.5) if findVo.call_back then findVo.call_back() end else self:MainRoleMoveAndCancel(co.TableXY(findVo.x, findVo.y), 0, findVo.call_back) end elseif findVo.type == FindVo.Figure then elseif findVo.type == FindVo.Thinking then elseif findVo.type == FindVo.Explore then local lx, ly = self.main_role:GetLogicPos() local range = findVo.range or 0 local function on_move_callback( ) GlobalEventSystem:Fire(EventName.FINDWAY_ENDED) local action_time = findVo.time or 0.3 action_time = action_time > 1 and action_time - 0.5 or action_time print("tanar: [Scene 6280]=> action_time: ",action_time) if action_time > 0 then local call_back = function ( ) if findVo.call_back then findVo.call_back() end end GlobalEventSystem:Fire(EventName.OPEN_COLLECT_VIEW, 0, 0, action_time, true, call_back) else if findVo.call_back then findVo.call_back() end end end if GameMath_GetDistance(lx, ly, findVo.x, findVo.y) <= 1 then on_move_callback() else self:MainRoleMoveAndCancel(co.TableXY(findVo.x, findVo.y), range, on_move_callback) end end end --[[ 功能:走到传送点 ]] function Scene:ToTheDoor() local door_vo = self.scene_mgr:GetTheDoorVo() if door_vo == nil then return false end self:MainRoleMoveToDoor(door_vo) return true end -- 跨场景,继续寻路 function Scene:FindContinue() if self.scene_mgr.find_nextvo then self:FindElement(self.scene_mgr.find_nextvo,self.find_isAgain) self.scene_mgr.find_nextvo = nil self.find_isAgain = nil end end --[[ 功能: 坐骑改变(场景通知) ]] function Scene:HorseChange(scmd) local scene_id = self.scene_mgr:GetSceneId() local scenne_action_cfg = Config.otherFightInfo.special_scene_action[scene_id] if scenne_action_cfg and scenne_action_cfg.is_hide_horse then scmd.is_ride = false return end local role_id = scmd.role_id local is_ride = scmd.is_ride local horse_id = scmd.figure_id local move_speed = scmd.speed local roleVo = self.scene_mgr:GetRoleVo(role_id) if roleVo ~= nil then roleVo:ChangeVar("move_speed", move_speed) roleVo:ChangeVar("is_ride",is_ride) roleVo:ChangeVar("horse_id", horse_id) else print("warning! can not find a role to handle move response!") end end --[[ 功能: 宠物改变(场景通知) ]] function Scene:PetChange(scmd) local role_id = scmd.role_id local pet_id = scmd.figure_id local pet_status = scmd.hide_status local roleVo = self.scene_mgr:GetRoleVo(role_id) if roleVo ~= nil then roleVo:ChangeVar("pet_id", pet_id) roleVo:ChangeVar("pet_status", pet_status) else print("warning! can not find a role to handle move response!") end end --[[ 功能: 宝宝改变(场景通知) ]] function Scene:BabyChange(scmd) local role_id = scmd.role_id local roleVo = self.scene_mgr:GetRoleVo(role_id) if roleVo ~= nil then roleVo:ChangeVar("child_follow_status", scmd.child_is_follow) roleVo:ChangeVar("child_sex", scmd.child_sex) roleVo:ChangeVar("child_ageMonth", scmd.child_age_month) --roleVo:ChangeVar("child_heartLinkLevel", scmd.heart_link_level) roleVo:ChangeVar("child_vehicle_id", scmd.vehicle_id) roleVo:ChangeVar("child_fashion", scmd.fashion_list) else print("warning! can not find a role to handle move response!") end end --[[ 功能: 时装改变(场景通知) ]] function Scene:FashionChange(scmd) local role_id = scmd.role_id local fashion_model_list = scmd.fashion_equip local roleVo = self.scene_mgr:GetRoleVo(role_id) if roleVo ~= nil then --时装变更时,需要清理珍宝和皮肤的数据 if FosterController.Instance then local temp_data = {type_id = scmd.pos, fashion_id = scmd.fashion_id, color_id = scmd.color_id} FosterController.Instance:ChangeRoleFashionInfo(temp_data,role_id) end roleVo.fashion_model_list = fashion_model_list roleVo:ChangeVar("fashion_model_list", fashion_model_list, nil, true) else print("warning! can not find a role to handle move response!") end end --[[ 功能: 光武改变(场景通知) ]] function Scene:LightWeaponChange(scmd) local role_id = scmd.role_id local light_weapon_model = scmd.light_weapon_model local roleVo = self.scene_mgr:GetRoleVo(role_id) if roleVo ~= nil then roleVo:ChangeVar("light_weapon_model", light_weapon_model, nil, true) else print("warning! can not find a role to handle move response!") end end --[[ 功能: 小精灵改变(场景通知) ]] function Scene:SpriteChange(scmd) local role_id = scmd.role_id local sprite_id = scmd.figure_id local roleVo = self.scene_mgr:GetRoleVo(role_id) if roleVo ~= nil then roleVo:ChangeVar("sprite_id", sprite_id) else print("warning! can not find a role to handle move response!") end end --[[ 功能: 式神改变(场景通知) ]] function Scene:GodChange(scmd) local role_id = scmd.role_id local god_id = scmd.god_id local hp = scmd.hp local hp_lim = scmd.hp_lim local roleVo = self.scene_mgr:GetRoleVo(role_id) if roleVo ~= nil then roleVo.god_max_hp = hp_lim roleVo:ChangeVar("god_id", god_id) roleVo:ChangeVar("god_hp", hp) -- roleVo:ChangeVar("god_max_hp", hp_lim) else print("warning! can not find a role to handle move response!") end end --[[ 功能: 场景角色属性改变(场景通知) ]] function Scene:RoleOtherProChange(role_id, scmd) local roleVo = self.scene_mgr:GetRoleVo(role_id) if roleVo ~= nil then print("12010--------RoleOtherProChange---------") for i,v in ipairs(scmd) do if v.style == 1 then --等级衣服模型 roleVo:UpdateLevelModelList(1, v.value) roleVo:ChangeVar("fashion_model_list",roleVo.fashion_model_list, nil, true) elseif v.style == 2 then --等级武器模型 roleVo:UpdateLevelModelList(2, v.value) roleVo:ChangeVar("level_model_list",roleVo.level_model_list, nil, true) elseif v.style == 3 then --等级头部模型 roleVo:UpdateLevelModelList(3, v.value) roleVo:ChangeVar("fashion_model_list",roleVo.fashion_model_list, nil, true) elseif v.style == 4 then --降神变化通知 roleVo:ChangeVar("god_id", v.value) elseif v.style == 5 then roleVo:ChangeVar("pokemon_id", v.value) elseif v.style == 6 then roleVo:ChangeVar("escort_state", v.value) elseif v.style == 7 then --活跃度形象 roleVo:ChangeVar("image_id", v.value) elseif v.style == 8 then roleVo:ChangeVar("protect_time", v.value) elseif v.style == 9 then roleVo:ChangeVar("deity_id", v.value) elseif v.style == 10 then--羁绊对象名 roleVo:ChangeVar("mate_name", v.value) elseif v.style == 11 then--羁绊称号名 roleVo:ChangeVar("mate_title", v.value) elseif v.style == 12 then--羁绊等级 roleVo:ChangeVar("mate_lv", tonumber(v.value)) elseif v.style == 13 then--跟随 roleVo:ChangeVar("evil_id", tonumber(v.value)) end end else -- print("warning! can not find a role to handle move response!") end end --改变玩家活动通用标志 function Scene:FlagChange(role_id, scmd) local roleVo = self.scene_mgr:GetRoleVo(role_id) -- 获取不到玩家数据的话,检测加载缓存列表的数据 local is_delay_vo = false if not roleVo then roleVo = self.scene_mgr:GetDelayRoleVo(role_id) is_delay_vo = true end if roleVo ~= nil and scmd then if roleVo.activity_flags == nil then roleVo.activity_flags = {} end for i,v in ipairs(scmd) do local find = false for j,vo in ipairs(roleVo.activity_flags) do if v.key == vo.key then vo.value = v.value find = true break end end if find == false then local obj = {} obj.key = v.key obj.value = v.value table_insert(roleVo.activity_flags, obj) end end if not is_delay_vo then roleVo:ChangeVar("activity_flags",roleVo.activity_flags, nil, true) end else --print("warning! can not find a role to handle move response!") end end --从列表中获取离主角最近的场景对象 function Scene:FindNearestSceneObj(src_list) if src_list == nil or not self.main_role then return end local min_dist_pow = nil local min_dist_obj = nil local scene_obj = nil local x1, y1 = self.main_role:GetRealPos() for i, vo in pairs(src_list) do if vo.obj_type == SceneBaseType.Role or vo.obj_type == SceneBaseType.Fake_Role then scene_obj = self:GetRole(vo.id) else scene_obj = self:GetSceneObj(vo.id) end if scene_obj and not scene_obj:IsDead() and self.scene_mgr:IsCanAttackByMainRole(scene_obj:GetVo())then local x2, y2 = scene_obj:GetRealPos() local dist_pow = GameMath_GetDistance(x1, y1, x2, y2, false) if min_dist_pow == nil or dist_pow < min_dist_pow then min_dist_pow = dist_pow min_dist_obj = scene_obj end end end return min_dist_obj end function Scene:FindNearestSelectableTargets(find_type, n, find_way, area) if Scene.FIND_TARGET_TYPE.monster == find_type then local monster_list,left_num = self:FindNearestSelectableMonsters(n, find_way, area) return monster_list, left_num elseif Scene.FIND_TARGET_TYPE.role == find_type then local role_list,left_num = self:FindNearestSelectableRoles(n, find_way, area) return role_list, left_num elseif Scene.FIND_TARGET_TYPE.all == find_type then local role_list, monster_list, left_num = nil,nil,nil role_list,left_num = self:FindNearestSelectableRoles(n, find_way, area) monster_list,left_num = self:FindNearestSelectableMonsters(left_num,find_way, area) return monster_list, role_list end end function Scene:FindNearestSelectableRoles(n, find_way, area) if self.scene_mgr:IsSafeScene() then return {}, n end if n == 0 then return {}, 0 end local attacker = self.main_role if not attacker then return {}, n end local war_group1= attacker:GetVo().warGroup local my_dir = attacker:GetDirection() if my_dir then my_dir:normalise() end local x1, y1 = attacker:GetRealPos() local ret = {} for _, role in pairs(self.role_list) do local vo = role:GetVo() if vo then local war_group2 = vo.warGroup local same_group = war_group2 == war_group1 and war_group1 > 0 local canpkByPkStatus = true if select_type == 3 then--最近队友 辅助技能给自己队友加属性 if attacker_vo.team_id == vo.team_id and attacker_vo.team_id > 0 then same_group = false else same_group = true end elseif war_group1 == 0 and war_group2 == 0 then canpkByPkStatus = self.scene_mgr:CanPKByPKStatus(attacker.vo, vo) end local x2, y2 = role:GetRealPos() if role ~= attacker and canpkByPkStatus and not same_group and not role:IsDead() and not role.buff_manager:hasUnbeatableBuff() and not vo.is_virtual_friend and ( (self.scene_mgr:IsGuildWarScene() or not self.scene_mgr:IsSafeArea(nil, x2, y2)) and not role:HasModelHideFlag(SceneObj.ModelHideFlag.ServerHide)) then --计算距离(因为结果要按距离排序,所以必须要算) local dist_pw = GameMath_GetDistance(x1, y1, x2, y2, false) if dist_pw <= 2500 then --如果距离在(50,50)之内,就忽略距离判断和角度判断 table_insert(ret, {role, dist_pw}) else table_insert(ret, {role, dist_pw}) end end end end --对所有范围内的怪物按距离排序 local sort_func = function(t1, t2) return t1[2] < t2[2] end table_sort(ret, sort_func) local res = {} local left_num = n for i=1, n do local t = ret[i] if t == nil then break else table_insert(res, t[1]) left_num = left_num - 1 end end return res, left_num end --获取离玩家最近的可选怪物 --@find_way == : 寻找目标的方式,1:目标的类型(采集>boss>小怪) 2:血量 function Scene:FindNearestSelectableMonsters(n ,find_way,area) if self.scene_mgr:IsSafeScene() then return {}, n end if n == 0 then return {}, 0 end local attacker = self.main_role if not attacker then return {}, n end find_way = find_way or 1 local area_pw = area and (area * area) or nil local war_group1= attacker:GetVo().warGroup local my_dir = find_dir or attacker:GetDirection() if my_dir then my_dir:normalise() end local dot_min = find_radian and math.cos(find_radian / 2) or nil --左右各一半角度的cos值(dot值) local x1, y1 = attacker:GetRealPos() local ret = {} --把所有在距离内的、角度范围内的怪物找出来 for _, monster in pairs(self.monster_list) do local vo = monster:GetVo() if vo then local at = attacker:GetType() local war_group2 = vo.warGroup local same_group = (at == SceneBaseType.Monster and war_group2 == war_group1) or ((at == SceneBaseType.Role or at == SceneBaseType.MainRole) and war_group2 == war_group1 and war_group1 > 0) local is_mine = monster.role_id == RoleManager.Instance.mainRoleInfo.role_id local x2, y2 = monster:GetRealPos() local sort_type = 0 if find_way == 1 then if vo.type == MonsterType.TASK_COLLECT or vo.type == MonsterType.COLLECT or vo.type == MonsterType.UD_COLLECT then sort_type = 999 elseif vo.boss_type > 0 then sort_type = 899 + vo.boss_type else sort_type = 799 end elseif find_way == 2 then sort_type = 999 + vo.hp/vo.maxHp end if monster ~= attacker and not same_group and not monster:IsDead() and vo.guaji_flag == 0 and vo.can_attack == 1 and not monster.buff_manager:hasUnbeatableBuff() and vo.type ~= MonsterType.PICK and not monster:HasModelHideFlag(SceneObj.ModelHideFlag.ServerHide) and not is_mine then --计算距离(因为结果要按距离排序,所以必须要算) local dist_pw = GameMath_GetDistance(x1, y1, x2, y2, false) if dist_pw <= 2500 then --如果距离在(50,50)之内,就忽略距离判断和角度判断 table_insert(ret, {monster, dist_pw, sort_type}) --进行角度范围判定 攻击距离为半径,攻击范围为角度的扇形 elseif area_pw == nil or dist_pw <= area_pw then --圆形 table_insert(ret, {monster, dist_pw, sort_type}) end end end end --对所有范围内的怪物排序,先按(采集怪,boss怪,精英怪,普通怪)的怪物类型排序,如果类型相同,按距离排序 local sort_func = function(t1, t2) if t1[3] == t2[3] then return t1[2] < t2[2] else return t1[3] > t2[3] end end table_sort(ret, sort_func) local res = {} local left_num = n for i=1, n do local t = ret[i] if t == nil then break else table_insert(res, t[1]) left_num = left_num - 1 end end return res, left_num end --获取离玩家最近的怪物,可指定类型id, (boss怪>普通怪>采集怪) function Scene:FindNearestMonster(mon_id, distance, contain_collect_type) local distance = distance or self.pre_check_distance --预选目标的距离限制 local my_group = RoleManager.Instance.mainRoleInfo.warGroup local min_dist_mon, min_dist_pow = nil, nil -- 幻魔星域场景 没次数时不寻怪 local is_desert_scene = self.scene_mgr:IsBossDesertedScene() or self.scene_mgr:IsDesertedBossCrossScene() local support_boss = GuildModel:getInstance():GetGuildSupportBossId( )--要过滤掉当前协助的进攻对象 for _, monster in pairs(self.monster_list) do local mon_group = monster.vo.warGroup local same_group = my_group > 0 and my_group == mon_group --攻击者分组大于0的前提下才需要考虑是否相同分组 if monster and (not mon_id or monster.vo.type_id == mon_id) and not monster:IsDead() and not same_group then --再选类型 采集物 或者 可攻击怪物 if (contain_collect_type and self:MonsterIsCollect(monster.vo.type)) or (monster.vo.can_attack ~= 0 and not self:IsMonsterInvincible(monster)) -- 怪物不可攻击或者怪物进入无敌状态 and (monster.vo.role_id ~= RoleManager.Instance.mainRoleInfo.role_id) then if is_desert_scene then local rest_boss_time, rest_mon_time = BossModel:GetInstance():GetDesertedBossRestNum( ) if (support_boss == monster.vo.type_id) or --协助中 (rest_boss_time <= 0 and rest_mon_time > 0 and -- 仅有精英怪次数 打精英 monster.vo.boss_type == BossType.DesertedMonster) or (rest_boss_time > 0 and rest_mon_time <= 0 and -- 仅有BOSS次数 打BOSS monster.vo.boss_type == BossType.DesertedBoss) or (rest_boss_time > 0 and rest_mon_time > 0) -- 都有 then local x2, y2 = monster:GetRealPos() local x1, y1 = self.main_role:GetRealPos() local dist_pow = GameMath_GetDistance(x1, y1, x2, y2, false) if (not distance or dist_pow <= distance*distance) and (not min_dist_pow or dist_pow < min_dist_pow) then min_dist_pow = dist_pow min_dist_mon = monster end end else local can_check_mon = true --社团封印裂隙活动如果没有封印次数了忽略采集怪 if self:MonsterIsCollect(monster.vo.type) and self.scene_mgr:IsGuildScene() and GuildModel:getInstance():IsGuildCollectActive() and not GuildModel.Instance:CanCollect() then can_check_mon = false end --社团封印裂隙活动如果是标记了被别人采集中的采集怪,也要忽略掉 if self:MonsterIsCollect(monster.vo.type) and self.scene_mgr:IsGuildScene() and GuildModel:getInstance():IsGuildCollectActive() and GuildModel:getInstance():IsGuildIgnoreCollection(monster.vo.instance_id) then can_check_mon = false end --社团封印裂隙活动如果还有封印次数忽略普通怪 if not self:MonsterIsCollect(monster.vo.type) and self.scene_mgr:IsGuildScene() and GuildModel:getInstance():IsGuildCollectActive() and GuildModel.Instance:CanCollect() then can_check_mon = false end if can_check_mon then local x2, y2 = monster:GetRealPos() local x1, y1 = self.main_role:GetRealPos() local dist_pow = GameMath_GetDistance(x1, y1, x2, y2, false) if (not distance or dist_pow <= distance*distance) and (not min_dist_pow or dist_pow < min_dist_pow) then min_dist_pow = dist_pow min_dist_mon = monster end end end end end end return min_dist_mon end function Scene:MonsterIsCollect( monster_type ) if monster_type == MonsterType.COLLECT or monster_type == MonsterType.TASK_COLLECT or monster_type == MonsterType.UD_COLLECT then return true end return false end function Scene:IsMonsterInvincible(mon_obj) if mon_obj then if self.scene_mgr:IsRageWarScene() and mon_obj:GetVo().boss_type == BossType.UnDead -- 狂战领域追加了横幅,这个暂时屏蔽 and mon_obj:GetBuffVoByBuffTypeAndBuffId(SkillBuffType.UNBEATABLE, 1110000015) then -- 获取无敌buff return true end end return false end --获取离玩家最近的人物 function Scene:FindNearestRole(role_id, distance) local distance = distance or self.pre_check_distance --预选目标的距离限制 local min_dist_role, min_dist_pow = nil, nil for _, role in pairs(self.role_list) do if role and not role:IsDead() and self.scene_mgr:IsCanAttackByMainRole(role:GetVo(), true) then local x2, y2 = role:GetRealPos() local x1, y1 = self.main_role:GetRealPos() local dist_pow = GameMath_GetDistance(x1, y1, x2, y2, false) if (not distance or dist_pow <= distance*distance) and (not min_dist_pow or dist_pow < min_dist_pow) then min_dist_pow = dist_pow min_dist_role = role end end end return min_dist_role end --允许点击屏幕 function Scene:EnableClickScreen(bool) self.enable_click_screen = bool end -- 是否场景加载完毕 function Scene:IsSceneProloadFinish() if self.sceneLoadView and self.sceneLoadView:HasOpen() then return false end if not self.scene_data_loaded or not self.preload_res_is_loaded then return false end return true end function Scene:CreateGrave(grave_vo) local grave = self.grave_list[grave_vo.instance_id] if grave ~= nil then self.grave_pool:ReleaseObj(grave) self.grave_list[grave_vo.instance_id] = nil end grave = self.grave_pool:GetObjFreeList() if grave == nil then grave = Grave.New() end self.grave_list[grave_vo.instance_id] = grave grave:InitGraveVo(grave_vo) grave:LoadInfoFromVo() return grave, true end function Scene:DeleteGrave( grave_id ) local grave = self.grave_list[grave_id] if grave ~= nil then self.grave_pool:ReleaseObj(grave) self.grave_list[grave_id] = nil end end function Scene:GetGraveItem(id) return self.grave_list[id] end function Scene:GetHookRoleItem(id) return self.hook_role_list[id] end function Scene:IsProgressLoadFinish() return self.load_progress_finished end function Scene:IsNpcLoadFinish() return self.load_npc_finish end function Scene:PreLoadMapRes( scene_id,callback ) self.mapView:PreLoadMapRes( scene_id,callback ) end function Scene:DeletePreLoadMap() self.mapView:DeletePreLoadMap() end function Scene:SetFindMonsterPos(x,y) if x == nil or y == nil then self.find_monster_pos = false else self.find_monster_pos = co.TableXY(x,y) end end function Scene:SceneLoadViewOpenState( ) if self.sceneLoadView then return self.sceneLoadView:HasOpen() and not self.sceneLoadView.hide_load_progress end end function Scene:SetFirstLoadBgFinish(bool) self.is_first_load_bg_finish = bool end function Scene:IsFirstLoadBgFinish() return self.is_first_load_bg_finish end function Scene:UpdateRoleListNameBoard() for _, v in pairs(self.role_list) do v:UpdateNameBoard() end end --玩家手动操作之后,要重置一些缓存状态,避免切场景后继续自动寻路之类的 function Scene:ResetUserManulState( ) if self.main_role and self.main_role:IsInState(PoseState.FLY_SHOE_EFFECT) then return end self:CancelWaitQuest() self:clearGoToData() AutoFightManager:getInstance():SetFlyData(false) AutoFightController:getInstance().fly_data = {} self:ClearFindNextScene() end function Scene:CheckBuffBall( ) local role_vo = RoleManager.Instance.mainRoleInfo local ball_list = BaseDungeonModel:getInstance():GetBuffPosList( ) or {} local distabce = 0 if role_vo then for k,v in pairs(ball_list) do distabce = GameMath_GetDistance((v.x or 0), (v.y or 0), role_vo.pos_x, role_vo.pos_y) if distabce < 100*100 then --请求拾取 BaseDungeonModel:getInstance():Fire(BaseDungeonModel.REQUEST_CCMD_EVENT, 61078,v.buff_id,v.x or 0,v.y or 0) end end end end function Scene:CheckEscortDistance( ) do return end local role_vo = RoleManager.Instance.mainRoleInfo if not self.escort_model then self.escort_model = EscortModel:GetInstance() end if not self.escort_instance_id then self.escort_instance_id = self.escort_model:GetMyEscortCarInstanceId() end -- if not self.escort_car_distance then -- self.escort_car_distance = Config.Convoykv["convoy_move_range"].value_content - 100 -- end local distance = 0 if role_vo then local mon_vo = self:GetMonster(self.escort_instance_id) if mon_vo then local dis = GameMath_GetDistance(mon_vo.vo.pos_x,mon_vo.vo.pos_y, role_vo.pos_x, role_vo.pos_y, false) if dis < self.escort_car_distance * self.escort_car_distance then if self.is_in_escort_car_distance ~= 1 then--不是1 有可能是还没值 或者是 2(远离车状态)告诉服务端我进来了 self.is_in_escort_car_distance = 1 self.escort_model:Fire(EscortConst.REQUEST_SCMD_EVENT, 50010, self.is_in_escort_car_distance) self.escort_model:Fire(EscortConst.RUN_NEAR_CAR) end elseif dis > (self.escort_car_distance + 300) * (self.escort_car_distance + 300) then if self.is_in_escort_car_distance == 1 then--必须是1(靠近车推车状态) 才触发告诉服务端我离开了 self.is_in_escort_car_distance = 2 self.escort_model:Fire(EscortConst.REQUEST_SCMD_EVENT, 50010, self.is_in_escort_car_distance) end end else self.is_in_escort_car_distance = 2--找不到车了 就不是在车旁边了 算离开 end end end function Scene:CleanEscortInfo( ) self.escort_model = nil self.escort_instance_id = nil self.escort_car_distance = nil self.is_in_escort_car_distance = nil end function Scene:ChangeMainRoleScale( force ) if not self.main_role then return end print('Cat:Scene.lua[6956] data', self.scene_mgr:IsMirrorScene() , self.scene_mgr:IsLastMirrorScene()) --如果是镜像场景,不会走飞天落地,所以直接设置原大小 if SceneManager.Instance:NoLoadingViewScene() or SceneManager.Instance:IsBabyScene() or self.main_role:IsInState(PoseState.FLY_SHOE_EFFECT) or force then self.main_role:SetScale(1) else self.main_role:SetScale(0.001) end end function Scene:IsInPickAllDropState() return self.is_in_pick_all_state end