1193 lines
33 KiB
Plaintext
1193 lines
33 KiB
Plaintext
autoImport("SkillItemData")
|
||
autoImport("SkillDynamicInfo")
|
||
autoImport("EquipedSkills")
|
||
SkillProxy = class('SkillProxy', pm.Proxy)
|
||
SkillProxy.Instance = nil;
|
||
SkillProxy.NAME = "SkillProxy"
|
||
|
||
SkillProxy.UNLOCKPROSKILLPOINTS = 40
|
||
|
||
SkillProxy.ManulSkillsIndex = 1
|
||
SkillProxy.AutoSkillsIndex = 2
|
||
SkillProxy.AutoSkillsWithComboIndex = 3
|
||
|
||
--場景管理,場景的載入佇列管理等
|
||
|
||
function SkillProxy:ctor(proxyName, data)
|
||
self.proxyName = proxyName or SkillProxy.NAME
|
||
if(SkillProxy.Instance == nil) then
|
||
SkillProxy.Instance = self
|
||
end
|
||
|
||
if data ~= nil then
|
||
self:setData(data)
|
||
end
|
||
self.professionSkills = {}
|
||
self.transformProfess = SkillProfessData.new(99999,0)
|
||
--放到手動快捷欄的技能,hash表,key為skillidlevel
|
||
self.equipedSkills = {}
|
||
--放到自動快捷欄的技能,hash表,key為skillidlevel
|
||
self.equipedAutoSkills = {}
|
||
self.equipedSkillsArrays = {{},{},{}}
|
||
self.comboGetPrevious = {}
|
||
self.equipedAutoArrayDirty = false
|
||
self:ResetTransformSkills(0)
|
||
self.learnedSkills = {}
|
||
self.sameProfessionType = {}
|
||
--動態屬性數據,hash表,key為skillID
|
||
self.dynamicSkillInfos = {}
|
||
self:initSameProfessionType()
|
||
--
|
||
self:InitCombo()
|
||
FunctionSkillEnableCheck.Me():Launch()
|
||
end
|
||
|
||
function SkillProxy:InitCombo()
|
||
if(GameConfig.AutoSkillGroup) then
|
||
for k,v in pairs(GameConfig.AutoSkillGroup) do
|
||
if(#v>1) then
|
||
for i=#v,2,-1 do
|
||
self.comboGetPrevious[v[i]] = v[i-1]
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function SkillProxy:initSameProfessionType( )
|
||
for key,value in pairs(Table_Class) do
|
||
local singleItem = Table_Class[key]
|
||
self.sameProfessionType[singleItem.Type] = self.sameProfessionType[singleItem.Type] or {}
|
||
table.insert(self.sameProfessionType[singleItem.Type],singleItem)
|
||
end
|
||
for key,value in pairs(self.sameProfessionType) do
|
||
table.sort(value,function (l,r)
|
||
-- body
|
||
return l.id <= r.id
|
||
end)
|
||
local list = {}
|
||
for i=1,#value do
|
||
local cur = value[i]
|
||
local advanceClasses = cur.AdvanceClass
|
||
if(advanceClasses) then
|
||
for j=1,#advanceClasses do
|
||
local single = advanceClasses[j]
|
||
-- local tmp = list[tostring(single)] or {}
|
||
-- table.insert(tmp,cur)
|
||
list[tostring(single)] = cur
|
||
end
|
||
end
|
||
end
|
||
|
||
for i=1,#value do
|
||
local cur = value[i]
|
||
local singleData = list[tostring(cur.id)]
|
||
if(not singleData and key ~=0)then
|
||
singleData = Table_Class[1]
|
||
end
|
||
-- printRed("cur:"..cur.id)
|
||
-- if(key ~=0)then
|
||
-- printRed("pre:"..singleData.id)
|
||
-- end
|
||
cur.previousClasses = singleData
|
||
end
|
||
end
|
||
end
|
||
|
||
--在手動技能快捷欄里查詢sortid
|
||
function SkillProxy:GetEquipedSkillBySort(sortID)
|
||
for k,v in pairs(self.equipedSkills) do
|
||
if(v.sortID == sortID and v.sourceId ==0) then
|
||
return true
|
||
end
|
||
end
|
||
return false
|
||
end
|
||
|
||
function SkillProxy:GetEquipedSkillByGuid( skillId ,includeAuto)
|
||
local skill = self.equipedSkills[skillId]
|
||
if(skill == nil and includeAuto) then
|
||
skill = self:GetEquipedAutoSkillByGuid(skillId)
|
||
end
|
||
return skill
|
||
end
|
||
|
||
function SkillProxy:GetEquipedAutoSkillByGuid( skillId )
|
||
return self.equipedAutoSkills[skillId]
|
||
end
|
||
|
||
function SkillProxy:startCdTimeBySkillId( skillId )
|
||
local sortID = math.floor(skillId / 1000)
|
||
local skills = self.learnedSkills[sortID]
|
||
local findSkill = self:FindSkill(skillId)
|
||
local skillCD,skillDelayCD
|
||
if(findSkill and Game.Myself ~= nil) then
|
||
local skillInfo = Game.LogicManager_Skill:GetSkillInfo(findSkill:GetID())
|
||
-- if(findSkill.staticData.CD)
|
||
skillCD = skillInfo:GetCD(Game.Myself)
|
||
skillDelayCD = skillInfo:GetDelayCD(Game.Myself)
|
||
if(skills) then
|
||
local skill
|
||
for i=1,#skills do
|
||
skill = self:GetEquipedSkillByGuid(skills[i].guid,true)
|
||
if(skill == nil) then
|
||
skill = self:GetTransformedSkill(skills[i].id)
|
||
end
|
||
--自動欄組合
|
||
if(skill == nil) then
|
||
skill = skills[i]
|
||
end
|
||
self:_InnerStartCD(skill,skillCD,skillDelayCD)
|
||
end
|
||
else
|
||
self:_InnerStartCD(findSkill,skillCD,skillDelayCD)
|
||
end
|
||
GameFacade.Instance:sendNotification(SkillEvent.SkillStartEvent)
|
||
end
|
||
end
|
||
|
||
function SkillProxy:_InnerStartCD(skillItemData,skillCD,skillDelayCD)
|
||
if(skillItemData) then
|
||
--技能CD
|
||
if(skillCD) then
|
||
CDProxy.Instance:AddSkillCD(skillItemData.id,0,skillCD,skillCD)
|
||
end
|
||
--handle special cd
|
||
local staticData = skillItemData:GetStaticData()
|
||
if(staticData) then
|
||
local buff
|
||
if(Game.MapManager:IsPVPMode()) then
|
||
buff = staticData.Buff
|
||
else
|
||
buff = staticData.Pvp_buff
|
||
end
|
||
if(buff.self~=nil) then
|
||
local buffConfig,cdTime,buffcd
|
||
for i=1,#buff.self do
|
||
buffConfig = Table_Buffer[buff.self[i]]
|
||
if(buffConfig and buffConfig.BuffEffect and buffConfig.BuffEffect.type and buffConfig.BuffEffect.type=="AddSkillCD") then
|
||
buffcd = buffConfig.BuffEffect.cd
|
||
if(buffcd) then
|
||
for j=1,#buffcd do
|
||
cdTime = buffcd[j].time
|
||
CDProxy.Instance:AddSkillCDBySortID(buffcd[j].id,0,cdTime,cdTime)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
if(skillDelayCD and skillDelayCD>0) then
|
||
--技能公共CD
|
||
CDProxy.Instance:AddSkillCD(CDProxy.CommunalSkillCDID,0,skillDelayCD,skillDelayCD)
|
||
end
|
||
end
|
||
end
|
||
|
||
---------------new--------
|
||
function SkillProxy:HasEnoughSkillPoint(pro)
|
||
local p = self:FindProfessSkill(pro)
|
||
if(p) then
|
||
return p.points >=SkillProxy.UNLOCKPROSKILLPOINTS
|
||
end
|
||
return false
|
||
end
|
||
|
||
function SkillProxy:FindProfessSkill(pro,autoCreate)
|
||
if self.multiSaveId ~= nil then
|
||
local skills = SaveInfoProxy.Instance:GetProfessionSkill(self.multiSaveId, self.multiSaveType)
|
||
if skills ~= nil then
|
||
for i=1,#skills do
|
||
if pro == skills[i].profession then
|
||
return skills[i]
|
||
end
|
||
end
|
||
end
|
||
else
|
||
for i=1,#self.professionSkills do
|
||
if(pro==self.professionSkills[i].profession) then
|
||
return self.professionSkills[i]
|
||
end
|
||
end
|
||
end
|
||
|
||
if(autoCreate) then
|
||
local professData = SkillProfessData.new(pro,0)
|
||
local p = Table_Class[pro]
|
||
for i=1,#p.Skill do
|
||
professData:AutoFillAdd(p.Skill[i])
|
||
end
|
||
self:AddProfessSkill(professData)
|
||
return professData
|
||
end
|
||
return nil
|
||
end
|
||
|
||
function SkillProxy:FindSkill(skillID,profession)
|
||
local professionSkill = nil
|
||
if(profession) then
|
||
professionSkill = self:FindProfessSkill(profession)
|
||
if(professionSkill) then
|
||
return professionSkill:FindSkillById(skillID)
|
||
end
|
||
end
|
||
local skill
|
||
for i=1,#self.professionSkills do
|
||
skill = self.professionSkills[i]:FindSkillById(skillID)
|
||
if(skill) then
|
||
return skill
|
||
end
|
||
end
|
||
return self:GetTransformedSkill(skillID)
|
||
end
|
||
|
||
function SkillProxy:ServerReInit(serverData)
|
||
Game.Myself:Client_SetAutoFakeDead(0)
|
||
self.professionSkills = {}
|
||
self:ClearEquipedSkill()
|
||
self:ClearEquipedSkill(true)
|
||
self.learnedSkills = {}
|
||
local professSkill
|
||
for i=1,#serverData.data do
|
||
self:AddProfessSkill(self:CreateProfessSkill(serverData.data[i]))
|
||
end
|
||
end
|
||
|
||
function SkillProxy:ClearEquipedSkill(isAutoMode)
|
||
local t = isAutoMode and self.equipedAutoSkills or self.equipedSkills
|
||
for k,v in pairs(t) do
|
||
FunctionSkillEnableCheck.Me():RemoveCheckSkill(v)
|
||
end
|
||
if(isAutoMode) then
|
||
self.equipedAutoSkills = {}
|
||
self.equipedSkillsArrays[SkillProxy.AutoSkillsIndex] = {}
|
||
else
|
||
self.equipedSkills = {}
|
||
self.equipedSkillsArrays[SkillProxy.ManulSkillsIndex] = {}
|
||
end
|
||
end
|
||
|
||
function SkillProxy:CreateProfessSkill(serverSkillData)
|
||
local data
|
||
local skill
|
||
local professSkill = SkillProfessData.new(serverSkillData.profession,serverSkillData.usedpoint)
|
||
local shortCutAuto = ShortCutProxy.SkillShortCut.Auto
|
||
for j=1,#serverSkillData.items do
|
||
data = serverSkillData.items[j]
|
||
skill = professSkill:UpdateSkill(data)
|
||
-- SkillUtils.RefreshPlayerSkillData(data.id)
|
||
if self:_CheckPosInShortCut(skill) then
|
||
self:AddEquipSkill(skill)
|
||
end
|
||
if skill:GetPosInShortCutGroup(shortCutAuto) > 0 then
|
||
self:AddEquipSkill(skill,true)
|
||
end
|
||
if(skill.learned) then
|
||
self:LearnedSkill(skill)
|
||
end
|
||
end
|
||
professSkill:SortSkills()
|
||
professSkill:UpdateBasePoints(serverSkillData.primarypoint)
|
||
return professSkill
|
||
end
|
||
|
||
function SkillProxy:_CheckPosInShortCut(skill)
|
||
if skill ~= nil then
|
||
local _ShortCutEnum = ShortCutProxy.ShortCutEnum
|
||
for k,v in pairs(_ShortCutEnum) do
|
||
if skill:GetPosInShortCutGroup(v) > 0 then
|
||
return true
|
||
end
|
||
end
|
||
end
|
||
return false
|
||
end
|
||
|
||
function SkillProxy:AddProfessSkill(professSkill)
|
||
self.professionSkills[#self.professionSkills + 1] = professSkill
|
||
table.sort(self.professionSkills,function (l,r)
|
||
return l.profession < r.profession
|
||
end)
|
||
end
|
||
|
||
function SkillProxy:AddEquipSkill(skillItemData,isAutoMode)
|
||
local skilltable = isAutoMode and self.equipedAutoSkills or self.equipedSkills
|
||
local skill = skilltable[skillItemData.guid]
|
||
if(skill==nil or skill~=skillItemData) then
|
||
EventManager.Me():PassEvent(SkillEvent.SkillEquip,skillItemData)
|
||
skilltable[skillItemData.guid] = skillItemData
|
||
end
|
||
local skillArray = self:GetEquipedSkillsArray(isAutoMode)
|
||
if(skillItemData.shadow == false) then
|
||
local shortCutType
|
||
if isAutoMode then
|
||
shortCutType = ShortCutProxy.SkillShortCut.Auto
|
||
else
|
||
shortCutType = ShortCutProxy.ShortCutEnum.ID1
|
||
end
|
||
if(TableUtil.IndexOf(skillArray,skillItemData) == 0) then
|
||
local added = false
|
||
for i=1,#skillArray do
|
||
if(skillArray[i]:GetPosInShortCutGroup(shortCutType) > skillItemData:GetPosInShortCutGroup(shortCutType)) then
|
||
table.insert(skillArray,i,skillItemData)
|
||
added = true
|
||
break
|
||
elseif(skillArray[i]:GetPosInShortCutGroup(shortCutType) == skillItemData:GetPosInShortCutGroup(shortCutType)) then
|
||
skillArray[i] = skillItemData
|
||
added = true
|
||
break
|
||
end
|
||
end
|
||
if(not added) then
|
||
skillArray[#skillArray + 1] = skillItemData
|
||
end
|
||
if(isAutoMode) then
|
||
self.equipedAutoArrayDirty = true
|
||
if(skillItemData.staticData.SkillType == SkillType.FakeDead) then
|
||
Game.Myself:Client_SetAutoFakeDead(skillItemData:GetID())
|
||
end
|
||
end
|
||
else
|
||
table.sort(skillArray,function(l,r)
|
||
return l:GetPosInShortCutGroup(shortCutType) < r:GetPosInShortCutGroup(shortCutType)
|
||
end)
|
||
end
|
||
else
|
||
TableUtil.Remove(skillArray,skillItemData)
|
||
end
|
||
end
|
||
|
||
function SkillProxy:RemoveEquipSkill(skillItemData,isAutoMode)
|
||
local skilltable = isAutoMode and self.equipedAutoSkills or self.equipedSkills
|
||
skilltable[skillItemData.guid] = nil
|
||
local skillArray = self:GetEquipedSkillsArray(isAutoMode)
|
||
if(TableUtil.Remove(skillArray,skillItemData)>0)then
|
||
if(isAutoMode) then
|
||
self.equipedAutoArrayDirty = true
|
||
end
|
||
end
|
||
if(self.equipedAutoSkills[skillItemData.guid] == nil and self.equipedSkills[skillItemData.guid] ==nil) then
|
||
EventManager.Me():PassEvent(SkillEvent.SkillDisEquip,skillItemData)
|
||
end
|
||
if(isAutoMode and self.equipedAutoSkills[skillItemData.guid] == nil) then
|
||
if(skillItemData.staticData.SkillType == SkillType.FakeDead) then
|
||
Game.Myself:Client_SetAutoFakeDead(0)
|
||
end
|
||
end
|
||
end
|
||
|
||
function SkillProxy:LearnedSkill(skillItemData)
|
||
self.equipedAutoArrayDirty = true
|
||
local skills = self.learnedSkills[skillItemData.sortID]
|
||
if(not skills) then
|
||
skills = {}
|
||
self.learnedSkills[skillItemData.sortID] = skills
|
||
skills[1] = skillItemData
|
||
else
|
||
if(TableUtil.IndexOf(skills,skillItemData)==0) then
|
||
skills[#skills+1] = skillItemData
|
||
end
|
||
end
|
||
if(skillItemData.id == GameConfig.Expression_Blink.needskill) then
|
||
FunctionPlayerHead.Me():EnableBlinkEye()
|
||
end
|
||
|
||
local beings = self:GetSummonBeings(skillItemData.staticData)
|
||
if(beings and #beings>0) then
|
||
CreatureSkillProxy.Instance:SetEnableBeings(beings,true)
|
||
end
|
||
end
|
||
|
||
function SkillProxy:GetSummonBeings(staticData)
|
||
local Logic_Param = staticData.Logic_Param
|
||
if(Logic_Param) then
|
||
return Logic_Param.being_ids
|
||
end
|
||
end
|
||
|
||
function SkillProxy:RemoveLearnedSkill(skillItemData)
|
||
local skills = self.learnedSkills[skillItemData.sortID]
|
||
if(skills) then
|
||
TableUtil.Remove(skills,skillItemData)
|
||
if(#skills==0) then
|
||
self.learnedSkills[skillItemData.sortID] = nil
|
||
local beings = self:GetSummonBeings(skillItemData.staticData)
|
||
if(beings and #beings>0) then
|
||
CreatureSkillProxy.Instance:SetEnableBeings(beings,false)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function SkillProxy:GetUsedPoints()
|
||
if(self.usedPointDirty) then
|
||
self.usedPointDirty = false
|
||
self.totalUsedPoint = 0
|
||
for i=1,#self.professionSkills do
|
||
if(self.professionSkills[i].points) then
|
||
self.totalUsedPoint = self.totalUsedPoint + self.professionSkills[i].points
|
||
end
|
||
end
|
||
end
|
||
return self.totalUsedPoint
|
||
end
|
||
|
||
function SkillProxy:Update( data )
|
||
-- printRed("update")
|
||
local update = data.update
|
||
local del = data.del
|
||
local myself = Game.Myself;
|
||
local proId = myself.data.userdata:Get(UDEnum.PROFESSION);
|
||
local profess = nil
|
||
local professSkill
|
||
local data
|
||
local skill
|
||
for i=1,#del do
|
||
profess = del[i]
|
||
professSkill = self:FindProfessSkill(profess.profession)
|
||
if(professSkill) then
|
||
for j=1,#profess.items do
|
||
data = profess.items[j]
|
||
skill = professSkill:RemoveSkill(data)
|
||
if(skill) then
|
||
self:RemoveEquipSkill(skill)
|
||
self:RemoveEquipSkill(skill,true)
|
||
self:RemoveLearnedSkill(skill)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
for i=1,#update do
|
||
profess = update[i]
|
||
professSkill = self:FindProfessSkill(profess.profession)
|
||
if(professSkill) then
|
||
self.usedPointDirty = true
|
||
professSkill:UpdatePoints(profess.usedpoint)
|
||
local shortCutAuto = ShortCutProxy.SkillShortCut.Auto
|
||
for j=1,#profess.items do
|
||
data = profess.items[j]
|
||
-- LogUtility.InfoFormat("新增技能..{0} 職業:{1}",data.id,profess.profession)
|
||
skill = professSkill:UpdateSkill(data)
|
||
if(data.consume) then
|
||
GameFacade.Instance:sendNotification(SkillEvent.SkillWithUseTimesChanged,skill.id)
|
||
end
|
||
-- SkillUtils.RefreshPlayerSkillData(data.id)
|
||
if self:_CheckPosInShortCut(skill) then
|
||
self:AddEquipSkill(skill)
|
||
else
|
||
self:RemoveEquipSkill(skill)
|
||
end
|
||
if skill:GetPosInShortCutGroup(shortCutAuto) > 0 then
|
||
self:AddEquipSkill(skill,true)
|
||
else
|
||
self:RemoveEquipSkill(skill,true)
|
||
end
|
||
if(skill.learned) then
|
||
self:LearnedSkill(skill)
|
||
end
|
||
-- if(skill:getCdTime()>0) then
|
||
-- self:startCdTimeBySkillId(skill.id)
|
||
-- end
|
||
end
|
||
professSkill:UpdateBasePoints(profess.primarypoint)
|
||
professSkill:SortSkills()
|
||
else
|
||
self:AddProfessSkill(self:CreateProfessSkill(profess))
|
||
end
|
||
end
|
||
end
|
||
|
||
function SkillProxy:GetEquipedSkillsArray(isAuto)
|
||
if(isAuto) then
|
||
return self.equipedSkillsArrays[SkillProxy.AutoSkillsIndex]
|
||
else
|
||
return self.equipedSkillsArrays[SkillProxy.ManulSkillsIndex]
|
||
end
|
||
end
|
||
|
||
function SkillProxy:IsEquipedSkillEmpty(shortCutID)
|
||
local pos
|
||
for k,v in pairs(self.equipedSkills) do
|
||
pos = v:GetPosInShortCutGroup(shortCutID)
|
||
if pos ~= nil and pos ~= 0 then
|
||
return false
|
||
end
|
||
end
|
||
return true
|
||
end
|
||
|
||
--手動技能快捷欄數據,autoFill是否補全空欄上的數據,id技能快捷欄id
|
||
function SkillProxy:GetCurrentEquipedSkillData( autoFill ,shortCutID)
|
||
if(shortCutID==nil) then
|
||
shortCutID = ShortCutProxy.ShortCutEnum.ID1
|
||
end
|
||
if(autoFill) then
|
||
local equipedSkillData = {}
|
||
if(autoFill)then
|
||
for i=1,ShortCutData.CONFIGSKILLNUM do
|
||
local item = SkillItemData.new(0,i,nil,nil,nil,i)
|
||
item:SetPosInShortCutGroup(shortCutID, i)
|
||
equipedSkillData[i] = item
|
||
end
|
||
end
|
||
local pos
|
||
local equipedSkills
|
||
if self.multiSaveId ~= nil then
|
||
equipedSkills = SaveInfoProxy.Instance:GetEquipedSkills(self.multiSaveId, self.multiSaveType)
|
||
end
|
||
equipedSkills = equipedSkills or self.equipedSkills
|
||
for k,v in pairs(equipedSkills) do
|
||
if(autoFill)then
|
||
pos = v:GetPosInShortCutGroup(shortCutID)
|
||
if pos ~= nil and pos ~= 0 then
|
||
equipedSkillData[pos] = v
|
||
end
|
||
elseif(not v.shadow) then
|
||
table.insert(equipedSkillData,v)
|
||
end
|
||
end
|
||
if(not autoFill) then
|
||
local ID1 = ShortCutProxy.ShortCutEnum.ID1
|
||
table.sort(equipedSkillData,function(l,r)
|
||
return l:GetPosInShortCutGroup(ID1) < r:GetPosInShortCutGroup(ID1)
|
||
end)
|
||
end
|
||
return equipedSkillData
|
||
end
|
||
return self:GetEquipedSkillsArray(false)
|
||
end
|
||
|
||
--自動技能快捷欄數據
|
||
function SkillProxy:GetEquipedAutoSkillData(autoFill)
|
||
if(autoFill) then
|
||
local equipedSkillData = {}
|
||
if(autoFill)then
|
||
for i=1,ShortCutData.CONFIGAUTOSKILLNUM do
|
||
local item = SkillItemData.new(0,0,i)
|
||
equipedSkillData[i] = item
|
||
end
|
||
end
|
||
local equipedAutoSkills
|
||
if self.multiSaveId ~= nil then
|
||
equipedAutoSkills = SaveInfoProxy.Instance:GetEquipedAutoSkills(self.multiSaveId, self.multiSaveType)
|
||
end
|
||
equipedAutoSkills = equipedAutoSkills or self.equipedAutoSkills
|
||
local shortCutAuto = ShortCutProxy.SkillShortCut.Auto
|
||
for k,v in pairs(equipedAutoSkills) do
|
||
if(autoFill)then
|
||
equipedSkillData[v:GetPosInShortCutGroup(shortCutAuto)] = v
|
||
elseif(not v.shadow) then
|
||
table.insert(equipedSkillData,v)
|
||
end
|
||
end
|
||
local sproxy = ShortCutProxy.Instance
|
||
table.sort(equipedSkillData,function(l,r)
|
||
if sproxy:AutoSkillIsLocked(l:GetPosInShortCutGroup(shortCutAuto)) == sproxy:AutoSkillIsLocked(r:GetPosInShortCutGroup(shortCutAuto)) then
|
||
return l:GetPosInShortCutGroup(shortCutAuto) < r:GetPosInShortCutGroup(shortCutAuto)
|
||
end
|
||
return not sproxy:AutoSkillIsLocked(l:GetPosInShortCutGroup(shortCutAuto))
|
||
end)
|
||
return equipedSkillData
|
||
end
|
||
return self:GetEquipedSkillsArray(true)
|
||
end
|
||
|
||
function SkillProxy:GetEquipedAutoSkillNum(includeShadow)
|
||
local num = 0
|
||
local shortCutAuto = ShortCutProxy.SkillShortCut.Auto
|
||
for k,v in pairs(self.equipedAutoSkills) do
|
||
if(not v.shadow or (v.shadow and includeShadow)) then
|
||
if not ShortCutProxy.Instance:AutoSkillIsLocked(v:GetPosInShortCutGroup(shortCutAuto)) then
|
||
num = num + 1
|
||
end
|
||
end
|
||
end
|
||
return num
|
||
end
|
||
|
||
function SkillProxy:HasLearnedSkill(skillID)
|
||
local skill = self:GetLearnedSkillWithSameSort(skillID)
|
||
return skill~= nil and skill.id >= skillID
|
||
end
|
||
|
||
function SkillProxy:HasLearnedSkillBySort(skillSortID)
|
||
local skill = self:GetLearnedSkillBySortID(skillSortID)
|
||
return skill~= nil
|
||
end
|
||
|
||
function SkillProxy:GetLearnedSkill(skillID)
|
||
local sortID = math.floor(skillID / 1000)
|
||
local skills = self.learnedSkills[sortID]
|
||
if(skills) then
|
||
for i=1,#skills do
|
||
if(skills[i].id == skillID) then
|
||
return skills[i]
|
||
end
|
||
end
|
||
end
|
||
return nil
|
||
end
|
||
|
||
function SkillProxy:GetLearnedSkillWithSameSort(skillID)
|
||
local sortID = math.floor(skillID / 1000)
|
||
return self:GetLearnedSkillBySortID(sortID)
|
||
end
|
||
|
||
function SkillProxy:GetLearnedSkillBySortID(sortID)
|
||
local skills = self.learnedSkills[sortID]
|
||
return skills ~= nil and skills[1] or nil
|
||
end
|
||
|
||
function SkillProxy:ForbitUse(skillItemData)
|
||
if(skillItemData and skillItemData.staticData and skillItemData.staticData.ForbidUse~=nil) then
|
||
if(Game.MapManager:IsPVPMode_GVGDetailed()) then
|
||
return skillItemData.staticData.ForbidUse & SkillItemData.ForbidUse.GVG > 0
|
||
end
|
||
end
|
||
return false
|
||
end
|
||
|
||
function SkillProxy:SkillCanBeUsed(skillItem)
|
||
local myselfData = Game.Myself.data
|
||
if self:CanMagicSkillUse(skillItem) == false then
|
||
return false
|
||
end
|
||
if myselfData:HasLimitSkill() then
|
||
local skillID
|
||
if(type(skillItem)=="number") then skillID = skillItem
|
||
else skillID = skillItem:GetID() end
|
||
if myselfData:GetLimitSkillTarget(skillID) == nil then
|
||
return false
|
||
end
|
||
elseif myselfData:HasLimitNotSkill() then
|
||
local skillID
|
||
if type(skillItem) == "number" then
|
||
skillID = skillItem
|
||
else
|
||
skillID = skillItem:GetID()
|
||
end
|
||
if myselfData:GetLimitNotSkill(skillID) ~= nil then
|
||
return false
|
||
end
|
||
end
|
||
if(self:ForbitUse(skillItem)) then
|
||
return false
|
||
end
|
||
return (not self:IsInCD(skillItem) and self:HasEnoughSp(skillItem) and self:HasEnoughHp(skillItem) and self:IsFitPreCondition(skillItem) and self:HasFitSpecialCost(skillItem)) or false
|
||
end
|
||
|
||
function SkillProxy:SkillCanBeUsedByID(skillID, allowNoLearned)
|
||
local myselfData = Game.Myself.data
|
||
if myselfData:HasLimitSkill() then
|
||
if myselfData:GetLimitSkillTarget(skillID) == nil then
|
||
return false
|
||
end
|
||
elseif myselfData:HasLimitNotSkill() then
|
||
if myselfData:GetLimitNotSkill(skillID) ~= nil then
|
||
return false
|
||
end
|
||
end
|
||
local learnedSkill = self:GetLearnedSkill(skillID)
|
||
if(learnedSkill) then
|
||
if self:CanMagicSkillUse(learnedSkill) == false then
|
||
return false
|
||
end
|
||
local canBeUsed = (not self:IsInCD(learnedSkill) and self:HasEnoughSp(learnedSkill) and self:HasEnoughHp(learnedSkill) and self:IsFitPreCondition(learnedSkill) and self:HasFitSpecialCost(learnedSkill)) or false
|
||
if(self:ForbitUse(skillItem)) then
|
||
return false
|
||
end
|
||
-- if not canBeUsed then
|
||
-- print(string.format("<color=red>skill(%d)</color> InCD=%s, HasSP=%s, FitPreCondion=%s",
|
||
-- skillID,
|
||
-- tostring(self:IsInCD(learnedSkill)),
|
||
-- tostring(self:HasEnoughSp(learnedSkill)),
|
||
-- tostring(self:IsFitPreCondition(learnedSkill))))
|
||
-- end
|
||
return canBeUsed
|
||
else
|
||
learnedSkill = self:FindSkill(skillID)
|
||
if(learnedSkill) then
|
||
return self:SkillCanBeUsed(learnedSkill)
|
||
end
|
||
return allowNoLearned or false
|
||
end
|
||
end
|
||
|
||
function SkillProxy:IsInCD(skillItem)
|
||
if(skillItem) then
|
||
if(skillItem.staticData.id == Game.Myself.data:GetAttackSkillIDAndLevel()) then
|
||
return false
|
||
end
|
||
return CDProxy.Instance:SkillIsInCD(skillItem.sortID)
|
||
end
|
||
return true
|
||
-- return skillItem:getCdTime()>0
|
||
end
|
||
|
||
function SkillProxy:IsFitPreCondition(skillItem)
|
||
return skillItem.fitPreCondion
|
||
end
|
||
|
||
function SkillProxy:HasEnoughSp(skillItem,sp)
|
||
local myself = Game.Myself
|
||
if(myself.data:IsTransformed()) then
|
||
return true
|
||
end
|
||
if(sp == nil) then
|
||
sp = myself.data.props.Sp:GetValue()
|
||
end
|
||
return self:_HasEnoughProp(myself,skillItem,"GetSP",sp)
|
||
end
|
||
|
||
function SkillProxy:HasEnoughHp(skillItem,hp)
|
||
local myself = Game.Myself
|
||
if(hp == nil) then
|
||
hp = myself.data.props.Hp:GetValue()
|
||
end
|
||
return self:_HasEnoughProp(myself,skillItem,"GetHP",hp)
|
||
end
|
||
|
||
function SkillProxy:_HasEnoughProp(myself,skillItem,skillInfoFuncName,value)
|
||
local skillID
|
||
if(type(skillItem)=="number") then skillID = skillItem
|
||
else skillID = skillItem:GetID() end
|
||
local skillInfo = Game.LogicManager_Skill:GetSkillInfo(skillID)
|
||
if(skillInfo) then
|
||
--備戰精英
|
||
if skillID == 50066001 then
|
||
local cost = self:GetCombatEliteSpCost();
|
||
if(cost and value < cost) then
|
||
return false
|
||
else
|
||
return true
|
||
end
|
||
else
|
||
local func = skillInfo[skillInfoFuncName]
|
||
if(func) then
|
||
local cost = func(skillInfo,myself)
|
||
if(cost and value < cost) then
|
||
return false
|
||
else
|
||
return true
|
||
end
|
||
end
|
||
end
|
||
end
|
||
return false
|
||
end
|
||
|
||
--備戰精英
|
||
|
||
function SkillProxy:GetProfessSkills()
|
||
local myProfess = SkillProxy.Instance:GetMyProfession()
|
||
local professTree = ProfessionProxy.Instance:GetProfessionTreeByClassId(myProfess)
|
||
|
||
datas = {};
|
||
|
||
if(professTree~=nil) then
|
||
--如果不是初心者的話(找到職業技能樹),才需要顯示職業技能
|
||
|
||
local professes = {}
|
||
local skills = {}
|
||
local p = professTree.transferRoot
|
||
local ps = nil
|
||
local typeBranch = Table_Class[myProfess].TypeBranch
|
||
|
||
local mydepth = professTree:GetProfessDataByClassID(myProfess).depth;
|
||
while p~=nil do
|
||
--[[
|
||
ps = SkillProxy.Instance:FindProfessSkill(p.id,true)
|
||
professes[#professes + 1] = ps
|
||
TableUtil.InsertArray(skills, ps.skills)
|
||
|
||
-- 一轉職業不顯示2、3轉技能
|
||
if(mydepth == 1)then
|
||
break;
|
||
end
|
||
]]
|
||
ps = SkillProxy.Instance:FindProfessSkill(p.id)
|
||
if (ps) then
|
||
professes[#professes + 1] = ps
|
||
TableUtil.InsertArray(skills, ps.skills)
|
||
end
|
||
|
||
-- 一轉職業不顯示2、3轉技能
|
||
if(mydepth == 1)then
|
||
break;
|
||
end
|
||
|
||
p = p:GetNextByBranch(typeBranch)
|
||
end
|
||
--設定技能選擇列表
|
||
--self.optionList:ResetDatas(skills)
|
||
|
||
for i=1,#skills do
|
||
if(skills[i].staticData.SkillType == "Buff" and skills[i].learned and (skills[i].staticData.Logic == 'SkillNone' or skills[i].staticData.Logic =='SkillSelfRange')) then
|
||
datas[#datas+1] = skills[i].staticData;
|
||
end
|
||
end
|
||
end
|
||
|
||
return datas;
|
||
end
|
||
|
||
function SkillProxy:GetCombatEliteOptionSkills()
|
||
|
||
local skills = SkillProxy.Instance:GetProfessSkills();
|
||
local datas = {};
|
||
local skillOptions = SkillProxy.Instance:FindSkillOptions();
|
||
|
||
for i=1,#skills do
|
||
local skillData = skills[i];
|
||
local optId = math.floor(skillData.id/1000);
|
||
if(TableUtil.HasValue(skillOptions, optId)) then
|
||
datas[#datas+1] = skills[i];
|
||
end
|
||
end
|
||
|
||
return datas;
|
||
|
||
end
|
||
|
||
function SkillProxy:GetCombatEliteSpCost()
|
||
|
||
local skills = self: GetCombatEliteOptionSkills();
|
||
local totalSpCost = 0;
|
||
|
||
for i=1,#skills do
|
||
local skillData = skills[i]
|
||
local spCost = 0;
|
||
if (skillData.SkillCost ~= nil and skillData.SkillCost.sp ~= nil) then
|
||
spCost = skillData.SkillCost.sp;
|
||
end
|
||
totalSpCost = totalSpCost + spCost;
|
||
end
|
||
|
||
return totalSpCost;
|
||
|
||
end
|
||
|
||
function SkillProxy:HasValue (tab, val)
|
||
for index, value in ipairs(tab) do
|
||
if value == val then
|
||
return true
|
||
end
|
||
end
|
||
|
||
return false
|
||
end
|
||
|
||
function SkillProxy:FindSkillOptions ()
|
||
local array = {}
|
||
for i=1,7 do
|
||
local skillID = Game.SkillOptionManager:GetSkillOption(i+5)
|
||
if skillID > 0 then
|
||
array[i] = skillID
|
||
end
|
||
end
|
||
return array
|
||
end
|
||
|
||
function SkillProxy:HasFitSpecialCost(skillItem)
|
||
local myself = Game.Myself
|
||
if(myself.data:IsTransformed()) then
|
||
return true
|
||
end
|
||
local skillStaticData
|
||
if(type(skillItem)=="number") then skillStaticData = Table_Skill[skillItem]
|
||
else skillStaticData = skillItem:GetStaticData() end
|
||
if(skillStaticData) then
|
||
local dynamicSkillInfo = myself.data:GetDynamicSkillInfo(skillStaticData.id)
|
||
local dynamicAllSkillInfo = self:GetDynamicAllSkillInfo()
|
||
local isNoItem = dynamicAllSkillInfo ~= nil and dynamicAllSkillInfo:GetIsNoItem()
|
||
if(#skillStaticData.SkillCost>0) then
|
||
local specialCost,num
|
||
for i=1,#skillStaticData.SkillCost do
|
||
specialCost = skillStaticData.SkillCost[i]
|
||
if specialCost.itemID and not isNoItem then
|
||
if(dynamicSkillInfo~=nil) then
|
||
num = dynamicSkillInfo:GetItemNewCost(specialCost.itemID,specialCost.num)
|
||
else
|
||
num = specialCost.num
|
||
end
|
||
if(BagProxy.Instance:GetItemNumByStaticID(specialCost.itemID)<num) then
|
||
return false,Table_Item[specialCost.itemID],num,true
|
||
end
|
||
end
|
||
if(specialCost.buffID) then
|
||
num = specialCost.num
|
||
if(myself:GetBuffLayer(specialCost.buffID)<num) then
|
||
return false,"nil",num,false
|
||
end
|
||
end
|
||
end
|
||
elseif dynamicSkillInfo and dynamicSkillInfo.costs and not isNoItem then
|
||
for k,cost in pairs(dynamicSkillInfo.costs) do
|
||
if(cost[1]~=nil and cost[2]>0) then
|
||
if(BagProxy.Instance:GetItemNumByStaticID(cost[1])<cost[2]) then
|
||
return false,Table_Item[cost[1]],cost[2],true
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
return true
|
||
end
|
||
|
||
function SkillProxy:GetLearnedSkillLevelBySortID(sortID)
|
||
local skills = self.learnedSkills[sortID]
|
||
if(skills and #skills>0) then
|
||
return skills[1].level
|
||
end
|
||
return 0
|
||
end
|
||
|
||
function SkillProxy:HasAttackSkill(skills)
|
||
local hasAttackTypeSkill
|
||
for k,skillData in pairs(skills) do
|
||
if(skillData and skillData.staticData) then
|
||
local config = Table_SkillMould[skillData.sortID*1000 + 1]
|
||
if(config and config.Atktype and config.Atktype==1) then
|
||
hasAttackTypeSkill = true
|
||
break
|
||
end
|
||
end
|
||
end
|
||
return hasAttackTypeSkill
|
||
end
|
||
|
||
function SkillProxy:GetTransformedSkills()
|
||
if(self.dynamicTransformedSkills) then
|
||
return self.dynamicTransformedSkills:GetSkills()
|
||
end
|
||
return self.equipedTransformSkills
|
||
end
|
||
|
||
function SkillProxy:UpdateTransformedSkills(update,del,clear)
|
||
local data
|
||
-- if(del and self.dynamicTransformedSkills) then
|
||
-- for i=1,#del do
|
||
-- data = del[i]
|
||
-- skill = self.transformProfess:RemoveSkill(data)
|
||
-- if(skill) then
|
||
-- self.dynamicTransformedSkills:RemoveSkill(skill)
|
||
-- self:RemoveLearnedSkill(skill)
|
||
-- end
|
||
-- if(self.dynamicTransformedSkills:IsEmpty()) then
|
||
-- self.dynamicTransformedSkills = nil
|
||
-- end
|
||
-- end
|
||
-- end
|
||
if(update and #update >0) then
|
||
if(self.dynamicTransformedSkills==nil) then
|
||
self.dynamicTransformedSkills = TransformedEquipSkills.new("pos")
|
||
end
|
||
self.dynamicTransformedSkills:RefreshServerSkills(update)
|
||
elseif(self.dynamicTransformedSkills)then
|
||
self.dynamicTransformedSkills:RefreshServerSkills({})
|
||
end
|
||
if(clear) then
|
||
self.dynamicTransformedSkills = nil
|
||
end
|
||
end
|
||
|
||
function SkillProxy:ResetTransformSkills(monsterID)
|
||
if(monsterID==0) then
|
||
if(self.equipedTransformSkills) then
|
||
for i=1,#self.equipedTransformSkills do
|
||
self:RemoveLearnedSkill(self.equipedTransformSkills[i])
|
||
end
|
||
end
|
||
self.equipedTransformSkills = nil
|
||
self:UpdateTransformedSkills(nil,nil,true)
|
||
else
|
||
local monster = Table_Monster[monsterID]
|
||
if(monster) then
|
||
self.equipedTransformSkills = {}
|
||
local skills = monster.Transform_Skill
|
||
for i=1,#skills do
|
||
local skill = SkillItemData.new(skills[i],i,0,0,0)
|
||
self.equipedTransformSkills[#self.equipedTransformSkills+1] = skill
|
||
self:LearnedSkill(skill)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function SkillProxy:GetAutoBattleSkills()
|
||
if(self.equipedTransformSkills~=nil and #self.equipedTransformSkills>0) then
|
||
return self.equipedTransformSkills
|
||
end
|
||
-- return self:GetEquipedSkillsArray(true)
|
||
return self:GetEquipedAutoSkillData()
|
||
end
|
||
|
||
local _removeDuplicates = {}
|
||
function SkillProxy:GetAutoBattleSkillsWithCombo()
|
||
if(self.equipedTransformSkills ~=nil and #self.equipedTransformSkills>0) then
|
||
return self.equipedTransformSkills
|
||
end
|
||
local array = self.equipedSkillsArrays[SkillProxy.AutoSkillsWithComboIndex]
|
||
if(self.equipedAutoArrayDirty) then
|
||
self.equipedAutoArrayDirty = false
|
||
TableUtility.ArrayClear(array)
|
||
TableUtility.TableClear(_removeDuplicates)
|
||
|
||
local rawAutos = self:GetEquipedAutoSkillData()
|
||
local skill,sortID,comboPrevious
|
||
local shortCutAuto = ShortCutProxy.SkillShortCut.Auto
|
||
if(GameConfig.AutoSkillGroup) then
|
||
for k,v in pairs(GameConfig.AutoSkillGroup) do
|
||
local duplicateCount = 0
|
||
if(#v>1) then
|
||
for i=#v,1,-1 do
|
||
skill = self:GetLearnedSkillBySortID(v[i])
|
||
if skill and skill:GetPosInShortCutGroup(shortCutAuto) > 0 then
|
||
duplicateCount = duplicateCount + 1
|
||
if(duplicateCount>1) then
|
||
_removeDuplicates[skill:GetPosInShortCutGroup(shortCutAuto)] = 1
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
for i=#rawAutos,1,-1 do
|
||
skill = rawAutos[i]
|
||
if _removeDuplicates[skill:GetPosInShortCutGroup(shortCutAuto)] == nil then
|
||
-- helplog("準備遞迴",skill.id,skill.staticData.NameZh)
|
||
self:_RecursiveGetComboPrevious(array,skill)
|
||
end
|
||
end
|
||
end
|
||
return array
|
||
end
|
||
|
||
function SkillProxy:_RecursiveGetComboPrevious( array,skill )
|
||
if(skill~=nil) then
|
||
comboPrevious = self.comboGetPrevious[skill.sortID]
|
||
--kick out passive and fake dead
|
||
if(skill.staticData.SkillType ~= GameConfig.SkillType.Passive.type and skill.staticData.SkillType ~= SkillType.FakeDead) then
|
||
table.insert(array,1,skill)
|
||
end
|
||
if(comboPrevious ~= nil) then
|
||
skill = self:GetLearnedSkillBySortID(comboPrevious)
|
||
while (skill == nil and comboPrevious~=nil) do
|
||
comboPrevious = self.comboGetPrevious[comboPrevious]
|
||
skill = self:GetLearnedSkillBySortID(comboPrevious)
|
||
end
|
||
self:_RecursiveGetComboPrevious(array,skill)
|
||
end
|
||
end
|
||
end
|
||
|
||
function SkillProxy:GetTransformedSkill(id)
|
||
local skills = self:GetTransformedSkills()
|
||
if(skills~=nil and #skills>0) then
|
||
for i=1,#skills do
|
||
if(skills[i].id == id) then
|
||
return skills[i]
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function SkillProxy:RefreshSkills()
|
||
if(self.learnedSkills) then
|
||
for k,skills in pairs(self.learnedSkills) do
|
||
for i=1,#skills do
|
||
SkillUtils.RefreshPlayerSkillData(skills[i].id)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function SkillProxy:LearnedExpressionBlink()
|
||
return self:HasLearnedSkill(GameConfig.Expression_Blink.needskill)
|
||
end
|
||
|
||
function SkillProxy:Server_UpdateDynamicSkillInfos(serverData)
|
||
local dynamicServerData
|
||
local dynamicData
|
||
for i=1,#serverData.specinfo do
|
||
dynamicServerData = serverData.specinfo[i]
|
||
dynamicData = self.dynamicSkillInfos[dynamicServerData.id]
|
||
if(dynamicData==nil) then
|
||
dynamicData = SkillDynamicInfo.new()
|
||
self.dynamicSkillInfos[dynamicServerData.id] = dynamicData
|
||
end
|
||
dynamicData:SetServerInfo(dynamicServerData)
|
||
local skill = self:GetLearnedSkillBySortID(dynamicServerData.id)
|
||
if(skill) then
|
||
if self:_CheckPosInShortCut(skill) then
|
||
EventManager.Me():PassEvent(SkillEvent.SkillFitPreCondtion,skill)
|
||
end
|
||
end
|
||
end
|
||
|
||
if self.dynamicAllSkillInfo == nil then
|
||
self.dynamicAllSkillInfo = SkillDynamicInfo.new()
|
||
end
|
||
self.dynamicAllSkillInfo:SetServerInfo(serverData.allskillInfo)
|
||
end
|
||
|
||
--skillidlevel
|
||
function SkillProxy:GetDynamicSkillInfoByID(skillID)
|
||
local sortID = math.floor(skillID / 1000)
|
||
return self.dynamicSkillInfos[sortID]
|
||
end
|
||
|
||
function SkillProxy:GetDynamicAllSkillInfo()
|
||
return self.dynamicAllSkillInfo
|
||
end
|
||
|
||
function SkillProxy:GetSkillCanBreak()
|
||
if(MyselfProxy.Instance:HasJobBreak()) then
|
||
return self:GetUsedPoints()>=GameConfig.Peak.SkillPointToBreak
|
||
end
|
||
return false
|
||
end
|
||
|
||
function SkillProxy:SetMultiSave(multiSaveId, multiSaveType)
|
||
self.multiSaveId = multiSaveId
|
||
self.multiSaveType = multiSaveType
|
||
end
|
||
|
||
function SkillProxy:IsMultiSave()
|
||
return self.multiSaveId ~= nil
|
||
end
|
||
|
||
function SkillProxy:GetMyProfession()
|
||
if self.multiSaveId ~= nil then
|
||
local profession = SaveInfoProxy.Instance:GetProfession(self.multiSaveId, self.multiSaveType)
|
||
if profession ~= nil then
|
||
return profession
|
||
end
|
||
end
|
||
return MyselfProxy.Instance:GetMyProfession()
|
||
end
|
||
|
||
function SkillProxy:GetBeingNpcInfo(beingid)
|
||
if beingid == nil then
|
||
return nil
|
||
end
|
||
|
||
if self.multiSaveId == nil then
|
||
return PetProxy.Instance:GetMyBeingNpcInfo(beingid)
|
||
else
|
||
return SaveInfoProxy.Instance:GetBeingInfo(self.multiSaveId, beingid, self.multiSaveType)
|
||
end
|
||
end
|
||
|
||
function SkillProxy:CanMagicSkillUse(skillItem)
|
||
if skillItem == nil then
|
||
return false
|
||
end
|
||
|
||
if skillItem:IsMagicType() and Game.Myself.data:NoMagicSkill() then
|
||
return false
|
||
end
|
||
|
||
return true
|
||
end |