Astrolabe_BordData = class("Astrolabe_BordData") AstrolabeProxy_Plate_Length = 100; Astrolabe_Origin_PointID = 10000; autoImport("Table_Astrolabe"); autoImport("Table_AstrolabeUI"); autoImport("Astrolabe_PlateData"); local ArrayPushBack = TableUtility.ArrayPushBack local TableClear = TableUtility.TableClear; local floor = math.floor local _ProfessionProxy local PointCountInit, TotalPointCount_Map = false, {}; local Default_TypeBranch = GameConfig.Astrolabe.Default_TypeBranch; local t_temp = {}; function Astrolabe_BordData:ctor() local mem1, mem2; mem1 = collectgarbage("count") _ProfessionProxy = ProfessionProxy.Instance; self.activePointsMap = {}; self.offPoints_IDMap = {}; self.add_EffectMap = {}; self.add_SpecialEffectMap = {}; self.specialEffectCountMap = {}; self.skillSpecialEffectEnable = {}; self:InitPlates(); self:InitPlatesBg(); mem2 = collectgarbage("count"); redlog("Astrolabe_BordData Created!", string.format("Mem:%skb", mem2 - mem1) ); end -- init function Astrolabe_BordData:InitPlates() self.platesMap = {}; for plateid, plateSData in pairs(Table_Astrolabe)do local plateData = Astrolabe_PlateData.new(self); plateData:ReInitData(plateSData); self.platesMap[plateid] = plateData; if(PointCountInit == false)then local unlock = plateData:GetUnlock(); local evo, lv = unlock.evo or 0, unlock.lv or 0; local _t = TotalPointCount_Map[ evo ]; if(_t == nil)then _t = {}; TotalPointCount_Map[ evo ] = _t; end if(_t[ lv ] == nil)then _t[ lv ] = plateData.point_count; else _t[ lv ] = _t[ lv ] + plateData.point_count; end end end PointCountInit = true; end function Astrolabe_BordData:InitPlatesBg() self.platesBgMap = {}; for id1,bgDatas in pairs(Table_AstrolabeUI)do for id2,bgData in pairs(bgDatas)do local cid = id1 * 10000 + id2; self.platesBgMap[cid] = bgData; end end return self.platesBgMap; end function Astrolabe_BordData:InitPlates_Prop(profession) self.profession = profession; local classData = profession and Table_Class[profession]; if(classData == nil)then return; end local typeBranch = classData and classData.TypeBranch; if(typeBranch == nil)then local class_typeid = classData.Type; typeBranch = Default_TypeBranch and Default_TypeBranch[class_typeid]; end if(typeBranch == nil or typeBranch == 0)then return; end local propTableName = "Table_Rune_" .. typeBranch; local propConfig = _G[propTableName]; if(propConfig == nil)then autoImport(propTableName); propConfig = _G[propTableName]; end if(propConfig == nil)then redlog("Not Find Rune_Config!", propTableName); return; end for guid, propData in pairs(propConfig)do local pointData = self:GetPointByGuid(guid); if(pointData)then pointData:SetPropData(propData.Attr); end end self:RefreshActiveEffectMap(); -- init staticData local sdataTableName = "Table_Rune"; local sConfig = _G[sdataTableName]; if(sConfig == nil)then autoImport(sdataTableName); sConfig = _G[sdataTableName]; end for id, sData in pairs(sConfig)do local pointData = self:GetPointByGuid(id); if(pointData)then pointData:SetStaticData(sData); end end end function Astrolabe_BordData:InitUnlockParam(profession, rolelevel) if(self.platesMap == nil)then return; end for k,plateData in pairs(self.platesMap)do plateData:SetProfession(profession); plateData:SetRoleLevel(rolelevel); end end -- init -- get function Astrolabe_BordData:GetPlateMap() return self.platesMap; end function Astrolabe_BordData:GetPlateBgDatas() return self.platesBgMap; end function Astrolabe_BordData:GetPlateData(plateid) return self.platesMap[ plateid ]; end function Astrolabe_BordData:GetPointByGuid(point_guid) local plateid = math.floor(point_guid/10000); local posid = point_guid%10000; return self:GetPointByPosInfo(plateid, posid); end function Astrolabe_BordData:GetPointByPosInfo(plateid, posid) local plateData = self.platesMap[plateid]; if(plateData == nil)then redlog(string.format("not find plateid:%s", plateid)); return; end return plateData:GetPointDataByPos(posid); end function Astrolabe_BordData:GetTotalPointCount(rolelv, profession) local depth = _ProfessionProxy:GetDepthByClassId(profession); local max_evo = depth; if(max_evo == 4)then if(not FunctionUnLockFunc.Me():CheckCanOpen(5002))then max_evo = 3; end end if(max_evo == 3)then if(not FunctionUnLockFunc.Me():CheckCanOpen(5001))then max_evo = 2; end end local result_count = 0; for evo, nums in pairs(TotalPointCount_Map)do if(evo <= max_evo)then for lv, num in pairs(nums)do if(lv <= rolelv)then result_count = result_count + num; end end end end return result_count; end function Astrolabe_BordData:GetActivePointsMap() return self.activePointsMap; end function Astrolabe_BordData:GetAdd_EffectMap() return self.add_EffectMap; end function Astrolabe_BordData:GetSkill_SpecialEffect(skillid) return self.add_SpecialEffectMap[skillid]; end function Astrolabe_BordData:GetSpecialEffectCount(specialEffectId) local count = self.specialEffectCountMap[specialEffectId] if(count == nil)then return 0; end local config = Table_RuneSpecial[specialEffectId] if(config.Type == 2) then local enable = self.skillSpecialEffectEnable[specialEffectId]; if(enable==false or enable == nil) then return 0; end end return count end function Astrolabe_BordData:GetOffPointsIDMap() return self.offPoints_IDMap; end -- get -- active function Astrolabe_BordData:Server_SetActivePoints(pids) for i=1,#pids do self:Server_ActivePoint(pids[i]); end end function Astrolabe_BordData:Server_ActivePoint(guid) local plateid, posid = math.floor(guid/10000), guid%10000; local pointData = self:GetPointByPosInfo(plateid, posid); if(pointData and not pointData:IsActive())then pointData:SetActive(true); local plateData = self.platesMap[plateid]; local pointMap = plateData:GetPointMap(); -- update innter_point off_state local innerConnect = pointData:GetInnerConnect(); for i=1,#innerConnect do local pointData2 = pointMap[innerConnect[i]]; local state2 = pointData2:GetState(); if(state2 < Astrolabe_PointData_State.Off)then pointData2:SetState(Astrolabe_PointData_State.Off); end end -- update innter_point off_state -- update outter_point off_state local outerConnect = pointData:GetOuterConnect(); if(outerConnect)then for i=1, #outerConnect do local outerPoint = self:GetPointByGuid(outerConnect[i]); local outerState = outerPoint:GetState(); if(outerState < Astrolabe_PointData_State.Off)then outerPoint:SetState(Astrolabe_PointData_State.Off); end end end -- update outter_point off_state self:UpdateActiveEffectMap( pointData ); self.activePointsMap[guid] = pointData; end end function Astrolabe_BordData:SkillSetSpecialEnable(specialEffectId, enabled) self.skillSpecialEffectEnable[ specialEffectId ] = enabled; end -- active function Astrolabe_BordData:RefreshPointState(point_guid, state) if(state == Astrolabe_PointData_State.Off)then self.offPoints_IDMap[ point_guid ] = 1; else self.offPoints_IDMap[ point_guid ] = nil; end end -- add effect function Astrolabe_BordData:UpdateActiveEffectMap(pointData) local isActive = pointData:IsActive(); local effect = pointData:GetEffect(); if(effect)then local add_EffectMap = self.add_EffectMap; for attriKey, value in pairs(effect)do if(isActive)then if(add_EffectMap[attriKey])then add_EffectMap[attriKey] = add_EffectMap[attriKey] + value; else add_EffectMap[attriKey] = value; end else if(add_EffectMap[attriKey])then add_EffectMap[attriKey] = add_EffectMap[attriKey] - value; end end end end -- TODO -- Special Effect local seid = pointData:GetSpecialEffect(); if(seid == nil)then return; end local effectData = Table_RuneSpecial[seid]; if(effectData == nil)then return; end local specialEffectCountMap = self.specialEffectCountMap; local count if(isActive)then count = specialEffectCountMap[seid] count = count == nil and 1 or count + 1 specialEffectCountMap[seid] = count else if(specialEffectCountMap[seid])then specialEffectCountMap[seid] = specialEffectCountMap[seid] - 1; if(specialEffectCountMap[seid] == 0)then specialEffectCountMap[seid] = nil; end end end local skillIds = effectData.SkillID; if(skillIds == nil)then return; end local add_SpecialEffectMap = self.add_SpecialEffectMap; if(isActive)then for i=1,#skillIds do local skillId = skillIds[i]; local ids = add_SpecialEffectMap[ skillId ]; if(ids == nil)then ids = {}; add_SpecialEffectMap[ skillId ] = ids; end if(ids[seid] == nil)then ids[seid] = 1; else ids[seid] = ids[seid] + 1; end end else for i=1,#skillIds do local skillId = skillIds[i]; local ids = add_SpecialEffectMap[ skillId ]; if(ids ~= nil and ids[seid] ~= nil)then ids[seid] = ids[seid] - 1; if(ids[seid] == 0)then ids[seid] = nil; if(next(ids) == nil)then add_SpecialEffectMap[ skillId ] = nil; end end end end end end -- add effect -- reset function Astrolabe_BordData:Server_ResetPoints(server_stars, noReset) for i=1,#server_stars do local id = server_stars[i]; if(id == Astrolabe_Origin_PointID)then if(noReset ~= true)then self:Reset(); return; end end self:Server_ResetPoint(server_stars[i]); end end function Astrolabe_BordData:Server_ResetPoint(guid) local pointData = self:GetPointByGuid(guid); if(pointData == nil)then return; end if(not pointData:IsActive())then return; end pointData:SetActive(false); pointData:SetState(Astrolabe_PointData_State.Lock); pointData:UpdateLockState(self); local plateid = math.floor(guid/10000); local plateData = self:GetPlateData(plateid); local pointMap = plateData:GetPointMap(); local innerConnect = pointData:GetInnerConnect(); for i=1,#innerConnect do local pointData2 = pointMap[innerConnect[i]]; pointData2:UpdateLockState(self); end local outerConnect = pointData:GetOuterConnect(); if(outerConnect)then for i=1, #outerConnect do local outerPoint = self:GetPointByGuid(outerConnect[i]); outerPoint:UpdateLockState(self); end end self:UpdateActiveEffectMap( pointData ); self.activePointsMap[ guid ] = nil; end function Astrolabe_BordData:Reset() local activePointsMap = self.activePointsMap; for activeid,pointData in pairs(activePointsMap)do pointData:SetState(Astrolabe_PointData_State.Lock); local innerConnect = pointData:GetInnerConnect(); for i=1,#innerConnect do local id = innerConnect[i] + pointData.plateid * 10000; local pointData2 = self:GetPointByGuid(id); pointData2:SetState(Astrolabe_PointData_State.Lock); end local outerConnect = pointData:GetOuterConnect(); if(outerConnect)then for i=1, #outerConnect do local id = outerConnect[i]; local outerPoint = self:GetPointByGuid(id); outerPoint:SetState(Astrolabe_PointData_State.Lock); end end end TableClear(activePointsMap); self:ResetAddEffect(plate); end function Astrolabe_BordData:ResetAddEffect() TableClear(self.add_EffectMap); TableClear(self.add_SpecialEffectMap); TableClear(self.specialEffectCountMap); TableClear(self.skillSpecialEffectEnable); end function Astrolabe_BordData:RefreshActiveEffectMap() self:ResetAddEffect(); for k,pointData in pairs(self.activePointsMap)do self:UpdateActiveEffectMap(pointData); end end -- reset function Astrolabe_BordData:CheckPlateIsUnlock(plateid) local plateData = self.platesMap[ plateid ]; if(plateData == nil)then error( string.format("Not Find Plate:%s", plateid) ); return; end return plateData:IsUnlock(); end function Astrolabe_BordData:CheckNeed_DoServer_InitPlate() local originPoint = self:GetPointByGuid(Astrolabe_Origin_PointID); if(not originPoint:IsActive())then TableClear(t_temp); t_temp[1] = Astrolabe_Origin_PointID; ServiceAstrolabeCmdProxy.Instance:CallAstrolabeActivateStarCmd(t_temp); end end local cutVertexes = {} function Astrolabe_BordData:ResetPoint(globalID) self:BuildUndirectedGraph() local deActivatedPoints = { [globalID] = true } if self:IsCutVertex(globalID) then for i=1, #cutVertexes[globalID] do self:GetAllChildren(cutVertexes[globalID][i], deActivatedPoints) end end --------------------LogStart------------------ -- local str = "" -- for k,_ in pairs(deActivatedPoints) do -- str = str .. k .. "\n" -- end -- Debug.Log(str) --------------------LogEnd-------------------- return deActivatedPoints end function Astrolabe_BordData:BuildUndirectedGraph() -- if not self.isNewestUndirectedGraph then self:ReuseTarjanCache() self:Tarjan(Astrolabe_Origin_PointID, nil) -- self.isNewestUndirectedGraph = true -- end end local TableAstrolabe = Table_Astrolabe local counter = 0 local visited = {} local dfn = {} local low = {} function Astrolabe_BordData:Tarjan(u, parent) local v, children, starID, astrolabeID = 0, 0, 0, 0 local connects, star = {}, {} visited[u] = true counter = counter + 1 dfn[u], low[u] = counter, counter astrolabeID = floor(u / 10000) starID = u % 10000 star = TableAstrolabe[astrolabeID].stars[starID] local activePointsMap = self:GetActivePointsMap() for i=1, #star do local connects = star[i] for k=1, #connects do local v = connects[k] if v < 10000 then v = v + astrolabeID * 10000 end if activePointsMap[v] then if not visited[v] then children = children + 1 self:Tarjan(v, u); if low[u] > low[v] then low[u] = low[v] end if not parent and children > 1 then -- Debug.Log("articulation point: " .. u) if not cutVertexes[u] then cutVertexes[u] = {} end ArrayPushBack(cutVertexes[u], v) end if parent and low[v] >= dfn[u] then -- Debug.Log("articulation point: " .. u) if not cutVertexes[u] then cutVertexes[u] = {} end ArrayPushBack(cutVertexes[u], v) end elseif v ~= parent then if low[u] > dfn[v] then low[u] = dfn[v] end end end end end end local queue = {} local head, last, parent, astrolabeID, starID = 0, 0, 0, 0, 0 function Astrolabe_BordData:GetAllChildren(root, deActivatedPoints) local RootLowValue = low[root] head = 0 last = 1 queue[last] = root deActivatedPoints[root] = true local activePointsMap = self:GetActivePointsMap() while last > head do head = head + 1 parent = queue[head] astrolabeID = floor(parent / 10000) starID = parent % 10000 star = TableAstrolabe[astrolabeID].stars[starID] for i=1, #star do local connects = star[i] for k=1, #connects do local id = connects[k] if id < 10000 then id = id + astrolabeID * 10000 end if not deActivatedPoints[id] and activePointsMap[id] and low[id] >= RootLowValue then deActivatedPoints[id] = true last = last + 1 queue[last] = id end end end end end function Astrolabe_BordData:IsCutVertex(globalID) return cutVertexes[globalID] end function Astrolabe_BordData:ReuseTarjanCache() counter = 0 cutVertexes = {} self:ReuseVisitedArray() end function Astrolabe_BordData:ReuseVisitedArray() for k,_ in pairs(visited) do visited[k] = false end end function Astrolabe_BordData:ClearTarjanCache() visited = {} dfn = {} low = {} cutVertexes = {} queue = {} end