SceneDropObj = SceneDropObj or BaseClass(EventDispatcher) local SceneDropObj = SceneDropObj local GameMath_GetDistance = GameMath.GetDistance function SceneDropObj:__init() self.obj_type = SceneBaseType.Drop self.drop_mgr = SceneDropManager:getInstance() self.guild_model = GuildModel:getInstance() self.scene_mgr = SceneManager:getInstance() self.scene = Scene.getInstance() self.nameboard_Manager = NameBoardManager.getInstance() self.nameboard_index = false self.name_board = false self.not_fly_float = false--不需要飞飘字 --根父容器 -- local view_path = "root/Canvas/SceneDropObj" -- local go = GameObject.Find(view_path) -- if go then -- local item = newObject(go) -- item.gameObject:SetActive(true) -- self.gameObject = item.gameObject -- item.transform:SetParent(panelMgr:GetParent("SceneObjContainer").transform) -- item.transform.localScale = Vector3.one -- item.transform.localPosition = Vector3.zero -- end self.gameObject = UiFactory.createChild(panelMgr:GetParent("SceneObjContainer").transform,UIType.SceneDropObj) --先用uifactory来创建该容器吧 日后再调整 self.transform = self.gameObject.transform self.item_parent = self.transform:Find("ItemCon") self.effect_parent = self.transform:Find("EffectCon") self.obj_parent = self.transform:Find("ItemCon/obj").transform self.item_icon_con = self.transform:Find("ItemCon/Icon").gameObject self.item_parent.localScale = Vector3.one * SceneModelScale self.icon_render = self.item_icon_con:GetComponent("SpriteRenderer") self.animator = self.item_parent.gameObject:GetComponent("Animator") self.effect_parent.localPosition = Vector3(0,-0.1,0) self.obj_parent.localPosition = Vector3(0,-0.1,0) --特效数组 self.particle_list = {} self.max_scale = 1 self.create_time = 0 --记录掉落创建时间 self.every_time = 30 --多少秒后其他人可以拾取归属掉落 self.state = 0 -- 1 作为抛物线 2 静止地面 3 等待发送协议 4 缩小 5 飞到角色身上 5 从角色身上飞到背包 9 变透明 10抛物线之后的第二个动画 self.step_start_time = 0 -- 步骤的开始时间 self.can_not_pick = false --服务端返回掉落不能拾取,就标记一下 self.last_pick_time = 0 --捡取时间 self.sound_id = 0 self.no_smooth_height = true self.effect_gameObject = false self.drop_model_gameObject = false self.add_effect_type = 0 -- 1通过缓存 2 通过接口 self.scene = Scene.Instance self.res_use_ref = {} self:InitEvents() end function SceneDropObj:GetDropVo() return self.vo end function SceneDropObj:InitEvents() local function onCanNotPickSceneDropItem(drop_id) --标记为不能拾取, 自动挂机不去捡, 但手动走过去还是会捡的 if self.drop_id == drop_id then self.can_not_pick = true self.state = 2 end end self.can_not_pick_up_id = GlobalEventSystem:Bind(SceneEventType.CAN_NOT_PICK_SCENE_DROP_ITEM, onCanNotPickSceneDropItem) local function onPickSceneDropItem(vo) if self.drop_id == vo.drop_id then self.can_pick = true end end self.pick_up_id = GlobalEventSystem:Bind(SceneEventType.PICK_SCENE_DROP_ITEM, onPickSceneDropItem) --掉落消失,相对于其他队友 --所有的人都会收到 local function onDismissDropItem(drop_id) local onCall = function ( ) if self.drop_id == drop_id and not self:IsPicking() then self.step_start_time = Status.NowTime self.state = 9 end end if SceneManager.Instance:IsBossMoneyScene() then onCall() else setTimeout(onCall, 0.5) --15053返回后再判断是否被自己拾取,如果是则不消失,进入状态4 end end self.dismiss_item_id = GlobalEventSystem:Bind(SceneEventType.DISMiSS_SCENE_DROP_ITEM, onDismissDropItem) -- 社团boss拾取特殊处理相关逻辑 -- 社团boss开始进入拾取进度 -- local function onStartPickGBossDrop(vo) -- if vo.drop_id == self.drop_id then -- local function delay_finish_pick() -- if self.drop_id and self.state == 2 or self.state == 3 then -- self.guild_model:Fire(GuildModel.PICK_UP_BOSS_DROP_ITEM, GuildModel.GBossPickOpty.Succeed, self.vo.drop_id) -- end -- end -- self:CancelGuildBossPickDelayId() -- self.gboss_pickup_delay_id = setTimeout(delay_finish_pick, 3 + 1) -- 多延迟1秒,方便采集界面的效果表现完整 -- end -- end -- self.on_start_pick_gboss_drop_id = GlobalEventSystem:Bind(SceneEventType.GBOSS_PICK_START, onStartPickGBossDrop) -- 社团boss假采集中断 -- local function onCancelGbossPick(drop_id) -- if self.drop_id == drop_id then -- self:CancelGuildBossPickDelayId() -- self.guild_model:Fire(GuildModel.PICK_UP_BOSS_DROP_ITEM,GuildModel.GBossPickOpty.Cancel, self.vo.drop_id) -- end -- end -- self.on_cancel_gboss_pick = GlobalEventSystem:Bind(SceneEventType.GBOSS_PICK_CANCEL, onCancelGbossPick) local function onRefeshDropItem() if self.gboss_need_refresh then self:InitDropVo(self.vo, self.center_x, self.center_y) self.gboss_need_refresh = false end end self.need_refresh_boss_info = self.guild_model:Bind(GuildModel.UPDATE_GUILD_BOSS_INFO, onRefeshDropItem) end function SceneDropObj:InitDropVo(vo,center_x,center_y) self.vo = vo self.center_x = center_x self.center_y = center_y self.drop_id = vo.drop_id self.compress_id = Scene.CompressObjId(SceneBaseType.Drop, self.drop_id) self.can_pick = vo.can_pick or false --是否能捡起,只有推送 15053 才能自己捡起 -- 遗忘之境默认自己能捡起来 self.fake_pick = vo.fake_pick or false--假掉落或直接拾取 -- 这个变量的作用是保证在社团场景中能等社团boss协议数据到达之后再次刷新掉落物品,防止掉落物信息和采集流程出错和重登掉落物的状态问题 self.gboss_need_refresh = false local is_in_gboss_event = false if self.scene_mgr:IsGuildScene() then is_in_gboss_event = self.guild_model:GetSepcialPickLogicOfGBoss() if not is_in_gboss_event then self.gboss_need_refresh = true end end if vo then local goods_Id, lock = GoodsModel:getInstance():GetMappingTypeId(vo.drop_type, vo.type_id) self.goods_basic = GoodsModel:getInstance():GetGoodsBasicByTypeId(goods_Id) if self.goods_basic then self.color = color or self.goods_basic.color or 1 local goods_icon = self.goods_basic.goods_icon self.item_name = self.goods_basic.goods_name if self.goods_basic.type == 11 and (self.goods_basic.subtype == 10 or self.goods_basic.subtype == 11)then --装备鉴定物, 碎片,显示鉴定物对应的装备图标 local type_id, _name, icon = EquipModel:getInstance():GetIdentifyGoodsNameAndIcon(self.goods_basic.type_id, RoleManager.Instance.mainRoleInfo.career, self.goods_basic.color) goods_icon = icon self.item_name = _name end if not self.nameboard_index then self.nameboard_index,self.name_board = self.nameboard_Manager:CreateNameBoard() end if self.name_board then self.name_board:SetGameObjectName(self.item_name) self.name_board:SetGoodsConVisible(true) self.name_board:SetGoodsName(Language.substitute("{1}", WordManager.GetGoodsColor(self.goods_basic.color, true), Trim(self.goods_basic.goods_name))) self.name_board:SetHpVisible(false) end local abName = "" local resName = "" local drop_icon = tonumber(vo.drop_icon) or 1 if not drop_icon or drop_icon == 0 then abName = "model_dropmodel_" .. 1 resName = "model_dropmodel_" .. 1 else abName = "model_dropmodel_" .. drop_icon resName = "model_dropmodel_" .. drop_icon end local loadDropModelCallBack = function(objs) if self.drop_model_gameObject then destroy(self.drop_model_gameObject, true) self.drop_model_gameObject = false end if self._use_delete_method then return end if not objs or not objs[0] then logWarn("cannot find drop res = "..drop_icon) return end self.drop_model_gameObject = newObject(objs[0]) self.drop_model_gameObject:SetActive(true) self.drop_model_gameObject.transform:SetParent(self.obj_parent) self.drop_model_gameObject.transform.localPosition = Vector3.zero self.drop_model_gameObject.transform.localRotation = Quaternion.identity self.drop_model_gameObject.transform.localScale = Vector3.one end if self.obj_parent and abName and resName then LuaResManager:getInstance():loadPrefab(self,abName,resName, loadDropModelCallBack, true) end -- print("Saber:SceneDropObj [165] self.vo.expire_time_stamp: ",self.vo.expire_time_stamp) if self.vo.expire_time_stamp and self.vo.expire_time_stamp ~= 0 then self:CancelTimer() local free_loot_time = TimeUtil:getServerTime() + self.every_time -- 可以自由拾取的时间戳 local cur_time = TimeUtil:getServerTime() local timer_func = function () cur_time = TimeUtil:getServerTime() -- print("Saber:SceneDropObj [172] cur_time: ",cur_time) if cur_time >= self.vo.expire_time_stamp then -- 道具超时,销毁 self:CancelTimer() if not self.can_pick and self.state ~= 9 then --消失 self.step_start_time = Status.NowTime self.state = 9 end elseif cur_time >= free_loot_time then --变成可拾取状态 if not self.can_pick and self.state ~= 9 then -- self:CancelTimer() self.step_start_time = Status.NowTime self.state = 2 end end end if not self.timer then self.timer = GlobalTimerQuest:AddPeriodQuest(timer_func, 1, -1) end else self:CancelTimer() end end self.create_time = Status.NowTime self.step_start_time = Status.NowTime if vo.no_anim then self:SetRealPos(vo.pos_x,vo.pos_y) self.state = 2 else self:SetRealPos(vo.pos_x,vo.pos_y) self.state = 10 self.animator:Play("drop_anim_1",-1,0.0) self.animator:Update(0) end self:SetAlpha(1) end self:SetItemScale(self.max_scale) self.effect_parent.gameObject:SetActive(false) --添加物品光效 local onDelay = function ( ) self.effect_parent.gameObject:SetActive(true) self:ClearShiquEffect() local effect_res = self:GetColorEffect() local gameObject = self.drop_mgr:GetObjFormPool(self,effect_res,effect_res) if gameObject then self.add_effect_type = 1 local gameObject_transform = gameObject.transform gameObject_transform:SetParent(self.effect_parent) SetLocalPosition(gameObject_transform,0,0,0) SetLocalRotation(gameObject_transform) self.effect_gameObject = gameObject else self.add_effect_type = 2 self.particle_id = ParticleManager:getInstance():AddTargetEffect( effect_res, self.compress_id, true, nil, nil, 7,nil,nil,1) end --播放声音 if self.vo.drop_type ~= 3 then self:PlaySound("epicitem_drop")--Epicitem_drop end end self:CancelDelayTimer() -- 判断是否使用掉落物的光效特效 if (vo.effect and vo.effect~="") or is_in_gboss_event then self.show_effect = true self.timer_id = setTimeout(onDelay, 0.4) end if self.vo.drop_type == 3 then self:PlaySound("gold_drop") end end function SceneDropObj:CancelDelayTimer( ) if self.timer_id then GlobalTimerQuest:CancelQuest(self.timer_id) self.timer_id = nil end end function SceneDropObj:PlaySound(res) if not self:CanPlaySound() then return end if lua_viewM.is_lock_screen then return end if lua_soundM then lua_soundM:StopEffect(self, LuaSoundManager.SOUND_TYPE.DROP, self.sound_id) self.sound_id = lua_soundM:PlayEffect(self, res,false,LuaSoundManager.SOUND_TYPE.DROP) end end function SceneDropObj:CancelTimer( ) if self.timer then GlobalTimerQuest:CancelQuest(self.timer) self.timer = nil end end --主动添加挂在自己身上的例子特效 function SceneDropObj:AddParticle(id,particle_tranform) particle_tranform.parent = self.effect_parent SetLocalPosition(particle_tranform) SetLocalScale(particle_tranform) self.particle_list[id] = particle_tranform end --删除挂在自己身上的特效 --is_acive = false 被动删除挂在自己身上的粒子特效 由特效播放完来调用 --is_acive = true 主动删除挂在自己身上的特效 会通知particlemanager去删除 默认false function SceneDropObj:RemoveParticle(id,is_acive) self.particle_list[id] = nil if is_acive then ParticleManager:getInstance():DelEffect(id) end end --主动删除挂在自己身上的所有粒子特效 通常是角色死亡 移除角色之类的 function SceneDropObj:RemoveAllParticle() for id,_ in pairs(self.particle_list) do ParticleManager:getInstance():DelEffect(id) end self.particle_list = {} end function SceneDropObj:Update(now_time, elapse_time) if self.state == 10 then self:DropFlyStep(now_time, elapse_time) elseif self.state == 2 then self:ExcuteStaticStep() elseif self.state == 3 then self:WaitForServerStep() elseif self.state == 4 then self:ScaleItemStep() elseif self.state == 9 then self:TransparentStep() end end function SceneDropObj:__delete() if self.pick_up_id then GlobalEventSystem:UnBind(self.pick_up_id) self.pick_up_id = nil end if self.dismiss_item_id then GlobalEventSystem:UnBind(self.dismiss_item_id) self.dismiss_item_id = nil end if self.fail_pick_up_id then GlobalEventSystem:UnBind(self.fail_pick_up_id) self.fail_pick_up_id = nil end if self.can_not_pick_up_id then GlobalEventSystem:UnBind(self.can_not_pick_up_id) self.can_not_pick_up_id = nil end if self.nameboard_index then self.nameboard_Manager:RemoveNameBoard(self.nameboard_index) self.nameboard_index = nil end if self.name_board then self.name_board:DeleteMe() self.name_board = nil end self:ClearShiquEffect() self:RemoveAllParticle() self:CancelTimer() self:CancelDelayTimer() lua_resM:clearReference(self.res_use_ref) lua_resM:clearReference(self) if self.drop_model_gameObject then destroy(self.drop_model_gameObject, true) self.drop_model_gameObject = false end if self.gameObject then destroy(self.gameObject, true) self.gameObject = nil end end function SceneDropObj:Show() return self.gameObject:SetActive(true) end function SceneDropObj:Hide() self.show_effect = false self.item_parent.localPosition = Vector3.zero if self.gameObject.activeSelf and self.vo.fake_pick then--如果是假掉落 要拾取到背包 local type_id = GoodsModel:getInstance():GetMappingTypeId(self.vo.drop_type, self.vo.type_id) local goods_list = {type_id} MainUIModel:getInstance():PlayGoodsFlyList(goods_list) if not self.not_fly_float then local float_list = {{goods_type_id = type_id,num = self.vo.drop_num}} MainUIModel:getInstance():AddFloatInfo(float_list,true) end end return self.gameObject:SetActive(false) end function SceneDropObj:GetState() return self.state end function SceneDropObj:SetRealPos(posx, posy) if self.real_pos == nil then self.real_pos = co.TableXY(posx,posy) else self.real_pos.x = posx self.real_pos.y = posy end self:UpdateModelPos(self.real_pos.x,self.real_pos.y) --更新位置到模型 end function SceneDropObj:GetRealPos() return self.real_pos.x, self.real_pos.y end function SceneDropObj:UpdateModelPos(posx, posy) if self.transform and not IsNull(self.transform) then local newHeight = self.scene:GetZoneHeight(posx/SceneObj.LogicRealRatio.x,posy/SceneObj.LogicRealRatio.y) --newHeight = newHeight + 0.7 --这里图片是中心点对其 所以要加上一半图片高度 图片是 74 像素 SetGlobalPosition3D(self.transform,posx/MainCamera.PixelsToUnits, posy/MainCamera.PixelsToUnits,SceneObjHeight.Obj + newHeight) if self.name_board then self.name_board:UpdatePos(posx, posy,SceneObjHeight.Obj + newHeight - 0.8) end end end function SceneDropObj:SetItemScale(scale) if scale > self.max_scale then scale = self.max_scale end self.item_parent.localScale = Vector3.one * scale * SceneModelScale end --设置身体的位置 真实坐标不变 function SceneDropObj:SetBodyXY(x,y) if self.item_parent.transform then SetLocalPosition(self.item_parent.transform, x / MainCamera.PixelsToUnits,y / MainCamera.PixelsToUnits,0) end if self.effect_parent.transform then SetLocalPosition(self.effect_parent.transform, x / MainCamera.PixelsToUnits,y / MainCamera.PixelsToUnits,0) end end function SceneDropObj:DropFlyStep() if self.state == 10 then local t = Status.NowTime - self.step_start_time if t > 0.5 then self.step_start_time = Status.NowTime self.state = 2 end end end function SceneDropObj:ExcuteStaticStep() if self.state == 2 then if self.can_pick == true then self.state=4 --野外掉落,服务端先通知已经捡了,这里播放完抛物线后直接进入4,掉落消失 return end local t = Status.NowTime - self.step_start_time local role_pos_x,role_pos_y local role_list = {} --守护或者人物都可以捡,所以用列表去判断 local main_role = self.scene:GetMainRole() if not main_role then return end table.insert(role_list, main_role) --主角 if not self.scene.only_main_role_pick and ItemUseModel:getInstance():HasWearEvil() and not self.guild_model:GetSepcialPickLogicOfGBoss() then if main_role and main_role.evil then table.insert(role_list, main_role.evil) --守护 end end if #role_list > 0 then -- local role_pos_x,role_pos_y = role:GetRealPos() for i,role in ipairs(role_list) do role_pos_x,role_pos_y = role:GetRealPos() local distance = GameMath_GetDistance(role_pos_x, role_pos_y, self.real_pos.x, self.real_pos.y,false) if t > 0.05 and distance < 75*75 then if self.fake_pick then if distance < 1000 then self.state = 4 GlobalEventSystem:DelayFire(EventName.EVIL_AUTO_PICK) return end end self.step_start_time = Status.NowTime --发送协议 if self.vo and not self.fake_pick then local time = Status.NowTime-self.last_pick_time if (self.vo.role_id == nil or self.vo.role_id == 0 or self.vo.role_id == RoleManager.Instance:GetMainRoleId() or self:IsOutTime() ) and time>2 then --社团boss击杀后5分钟内执行特殊拾取逻辑(模拟采集逻辑) if self.guild_model:GetSepcialPickLogicOfGBoss() then if role:IsInState(PoseState.MOVE) or role:IsInState(PoseState.JUMP) or (not role.GetIsCollecting or role:GetIsCollecting()) then else self.guild_model:Fire(GuildModel.PICK_UP_BOSS_DROP_ITEM, GuildModel.GBossPickOpty.Start, self.vo.drop_id) --如果是守护,则去重新检测,是否有东西可以拾取 break end else self.last_pick_time = Status.NowTime --如果处于一键拾取状态就不要协议拾取了 --如果在拾取的过程中,切换了场景,那就不发协议了(守护有可能还在捡) if not self.scene:IsInPickAllDropState() and self.vo.map_id == self.scene_mgr:GetSceneId() and not self.scene_mgr:IsReqChangeScene() then GoodsModel:getInstance():Fire(GoodsModel.PICK_UP_SCENE_DROP_ITEM, self.vo.drop_id) end self.state = 3 GlobalEventSystem:DelayFire(EventName.EVIL_AUTO_PICK) break end end end end end end end end --超过15秒, 其他人可拾取归属掉落 function SceneDropObj:IsOutTime( ) return Status.NowTime-self.create_time>=self.every_time end --等待服务器返回 function SceneDropObj:WaitForServerStep() if self.state == 3 then local t = Status.NowTime - self.step_start_time --有可能没有收到协议,那么十秒后就自动消失 if self.can_pick then self.step_start_time = Status.NowTime self.state = 4 end if t > 200 then self.step_start_time = Status.NowTime self.state = 9 end end end --飞到主角身上 function SceneDropObj:ScaleItemStep() if self.state == 4 then local t = Status.NowTime - self.step_start_time local scale = self.max_scale - t / 0.4 if scale < 0 then self.item_parent.gameObject:SetActive(false) self:ClearShiquEffect() self:ShowDropTip() self.step_start_time = Status.NowTime self.state = 7 end --self:SetItemScale(scale) end end --主角身上 function SceneDropObj:GetDropId() return self.drop_id end --主角身上 function SceneDropObj:CanPlaySound() return not self.no_anim end function SceneDropObj:IsFinishState() return self.state == 7 end function SceneDropObj:ReleaseObj() self:Hide() self:CancelTimer() self:CancelDelayTimer() self.last_pick_time = 0 self.no_anim = false self.can_not_pick = false self:ClearShiquEffect() self.item_parent.gameObject:SetActive(true) self.icon_render.sprite = nil if self.nameboard_index then self.nameboard_Manager:RemoveNameBoard(self.nameboard_index) self.nameboard_index = nil end if self.name_board then self.name_board:DeleteMe() self.name_board = nil end lua_resM:clearReference(self.res_use_ref) end function SceneDropObj:ClearShiquEffect( ) local effect_res = self:GetColorEffect() if self.particle_id then ParticleManager:getInstance():DelEffectByResName(effect_res, self.compress_id) self.particle_id = nil end if self.effect_gameObject and self.vo then self.drop_mgr:AddObjToPool(self,effect_res,effect_res,self.effect_gameObject) end self.effect_gameObject = false self.add_effect_type = 0 end function SceneDropObj:ResetObj() self:Show() end --state为2才能拾取,其他状态要么已拾取,要么还没播放抛物线 function SceneDropObj:IsCanPickUp() if self.vo then return (self.vo.role_id == 0 or self.vo.role_id == RoleManager.Instance:GetMainRoleId() or self:IsOutTime() ) and (self.state==2 or self.state == 10) and not self.can_not_pick end return false end --是否为自己的掉落物 function SceneDropObj:IsSelfDrop() if self.vo then return self.vo.role_id == RoleManager.Instance:GetMainRoleId() end return false end --正在被拾取中 function SceneDropObj:IsPicking( ) return self.can_pick end --飞到主角身上 function SceneDropObj:TransparentStep() if self.state == 9 then local t = Status.NowTime - self.step_start_time local alpha = 1 - t / 1 if alpha < 0 then alpha = 0 self.state = 7 end self:SetAlpha(alpha) end end function SceneDropObj:SetAlpha(alpha) if self.icon_render then self.icon_render.color = Color(1,1,1,alpha) end end function SceneDropObj:GetPickItemTip( ) local str = "" if self.vo and self.item_name then str = "获得 "..self.item_name .." x " .. self.vo.drop_num end return str end function SceneDropObj:ShowDropTip( ) -- local tip = self:GetPickItemTip() -- if tip ~= "" then -- Message.show(tip) -- end if self.vo and self.item_name then local goods_id = 0 local drop_num = self.vo.drop_num if self.vo.drop_type == 0 then --物品 goods_id = self.vo.type_id elseif self.vo.drop_type == 3 then --金币 goods_id = GoodsModel:getInstance():GetMappingTypeId(self.vo.drop_type) MainUIModel:getInstance():PlayGoodsFlyList({goods_id}) end end end function SceneDropObj:CancelGuildBossPickDelayId( ) if self.gboss_pickup_delay_id then TimerQuest.CancelQuest(GlobalTimerQuest,self.gboss_pickup_delay_id) self.gboss_pickup_delay_id = nil end end function SceneDropObj:GetColorEffect() if not self.goods_basic then return "" end local color = self.goods_basic.color local effect_res = "" if color == 5 then effect_res = "droppillar_1" elseif color == 4 then effect_res = "droppillar_2" elseif color == 3 then effect_res = "droppillar_3" end return effect_res end