NpcData = reusableClass("NpcData",CreatureDataWithPropUserdata) NpcData.PoolSize = 100 local NpcMonsterUtility = NpcMonsterUtility NpcData.NpcType = { Npc=1, Monster=2, Pet=3, } NpcData.NpcDetailedType = { NPC="NPC", GatherNPC="GatherNPC", SealNPC="SealNPC", WeaponPet="WeaponPet", Monster="Monster", MINI="MINI", MVP="MVP", Escort="Escort", SkillNpc="SkillNpc", FoodNpc = "FoodNpc", PetNpc="PetNpc", CatchNpc="CatchNpc", BeingNpc="BeingNpc", StageNpc="StageNpc", DeadBoss="DeadBoss", } NpcData.ZoneType = { ZONE_MIN = 0, ZONE_FIELD = 1, ZONE_TASK = 2, ZONE_ENDLESSTOWER = 3, ZONE_LABORATORY = 4, ZONE_SEAL = 5, ZONE_DOJO = 6, ZONE_MAX = 7, } local tempArray = {} -- local num = 0 -- Npc數據 function NpcData:ctor() NpcData.super.ctor(self) --npc靜態數據 self.staticData = nil --特殊標誌id self.uniqueid = nil --行為數據 self.behaviourData = BehaviourData.new() --性格 self.charactors = ReusableTable.CreateArray() --是否使用伺服器變更形象 self.useServerDressData = false end function NpcData:GetCamp() if(self.campHandler and self.campHandler.dirty) then self:SetCamp(self.campHandler:GetCamp()) end return self.camp end function NpcData:GetDefaultGear() return self.staticData.DefaultGear end function NpcData:NoPlayIdle() return 1 == self.staticData.DisableWait end function NpcData:NoPlayShow() return 1 == self.staticData.DisablePlayshow end function NpcData:NoAutoAttack() return 1 == self.staticData.NoAutoAttack end function NpcData:GetAccessRange() return self.staticData.AccessRange or 2 end function NpcData:IsNpc() return self.type == NpcData.NpcType.Npc end function NpcData:IsMonster() return self.type == NpcData.NpcType.Monster end function NpcData:IsPet() return self.type == NpcData.NpcType.Pet end function NpcData:IsMonster_Detail() return self.detailedType == NpcData.NpcDetailedType.Monster end function NpcData:IsBoss() return self.detailedType == NpcData.NpcDetailedType.MVP end function NpcData:IsMini() return self.detailedType == NpcData.NpcDetailedType.MINI end function NpcData:IsSkillNpc_Detail() return self.detailedType == NpcData.NpcDetailedType.SkillNpc end function NpcData:IsCatchNpc_Detail() return self.detailedType == NpcData.NpcDetailedType.CatchNpc end function NpcData:IsBeingNpc_Detail() return self.detailedType == NpcData.NpcDetailedType.BeingNpc end function NpcData:IsMusicBox() return self.staticData.id == GameConfig.Joy.music_npc_id or self.staticData.id == GameConfig.System.musicboxnpc; end local ElementNpcMap; local GetElementNpcMap = function () if(ElementNpcMap)then return ElementNpcMap; end local config = GameConfig.PvpTeamRaid.ElementNpcsID ElementNpcMap = {}; if(config ~= nil)then for i=1,#config do ElementNpcMap[config[i].npcid] = 1; end end return ElementNpcMap; end function NpcData:IsElementNpc() local map = GetElementNpcMap(); if(map == nil)then return; end local npcid = self.staticData and self.staticData.id; return npcid and map[npcid] == 1; end local ElementNpcMap_Mid; local GetElementNpcMap_Mid = function () if(ElementNpcMap_Mid)then return ElementNpcMap_Mid; end local buffConfig = GameConfig.PvpTeamRaid.BuffEffect; ElementNpcMap_Mid = {}; if(buffConfig ~= nil)then for npcid,_ in pairs(buffConfig)do ElementNpcMap_Mid[npcid] = 1; end end return ElementNpcMap_Mid; end function NpcData:IsElementNpc_Mid() if(not Game.MapManager:IsPVPMode_TeamPws())then return false; end local map = GetElementNpcMap_Mid(); if(map == nil)then return false; end local npcid = self.staticData and self.staticData.id; return npcid and map[npcid] == 1; end local normal_card_npc = GameConfig.CardRaid.normal_card_npc local boss_card_npc = GameConfig.CardRaid.boss_card_npc function NpcData:IsPveCardEffect() local sid = self.staticData and self.staticData.id or 0; return sid == normal_card_npc or sid == boss_card_npc; end function NpcData:GetStaticID() return self.staticData.id end function NpcData:GetBaseLv() local level if( nil ~= self.userdata ) then level = self.userdata:Get(UDEnum.ROLELEVEL) end if( nil == level ) then if( nil ~= self.staticData and nil ~= self.staticData.Level )then level = self.staticData.Level else level = 1 end end return level end function NpcData:NoHitEffectMove() if(self.behaviourData:GetNonMoveable()==1) then return true end return NpcData.super.NoHitEffectMove(self) end function NpcData:NoAttackEffectMove() if(self.behaviourData:GetNonMoveable()==1) then return true end return NpcData.super.NoAttackEffectMove(self) end --獲取體型 function NpcData:GetShape() return self.staticData.Shape end --獲取組id function NpcData:GetGroupID() return self.staticData.GroupID end --獲取種族 function NpcData:GetRace() return self.staticData.Race_Parsed end --獲取原始名字 function NpcData:GetOriginName() if self.staticData==nil or self.staticData.NameZh==nil then return "none" end return self.staticData.NameZh end function NpcData:GetName() return NpcData.WithCharactorName(self.charactors)..(self.name and self.name or self:GetOriginName()) end function NpcData:GetNpcID() return self.staticData.id end function NpcData:GetDefaultScale() if(self.staticData) then return self.staticData.Scale or 1 end return 1 end function NpcData:GetClassID() return 0 end --features start function NpcData:GetFeature(bit) if(self.staticData.Features) then return self.staticData.Features & bit >0 end return false end function NpcData:GetFeature_ChangeLinePunish() return self:GetFeature(1) end function NpcData:GetFeature_BeHold() return self:GetFeature(4) end function NpcData:GetFeature_FakeMini() return self:GetFeature(16); end function NpcData:GetFeature_IgnoreNavmesh() return self:GetFeature(32); end --features end --帶有性格的名字 function NpcData.WithCharactorName(charactors) local charactorNames = "" local charactorConf for i=1,#charactors do charactorConf = Table_Character[charactors[i]] if(charactorConf) then charactorNames = charactorNames..string.format(GameConfig.MonsterCharacterColor[charactorConf.NameColor],charactorConf.Name..(i==#charactors and ZhString.NpcCharactorSplit or "")) else errorLog(string.format("creature id:%s charactor cannot find config %s",self.id,charactors[i])) end end return charactorNames end function NpcData:SetBehaviourData(num) self.behaviourData:Set(num or 0) self.noPicked = self.behaviourData:GetSkillNonSelectable() end function NpcData:GetZoneType() local str = self.staticData.Zone if(str == "Field") then return NpcData.ZoneType.ZONE_FIELD elseif(str == "Task") then return NpcData.ZoneType.ZONE_TASK elseif(str == "EndlessTower") then return NpcData.ZoneType.ZONE_ENDLESSTOWER elseif(str == "Laboratory") then return NpcData.ZoneType.ZONE_LABORATORY elseif(str == "Repair") then return NpcData.ZoneType.ZONE_SEAL elseif(str == "Dojo") then return NpcData.ZoneType.ZONE_DOJO end end function NpcData:SetUseServerDressData(v) self.useServerDressData = v end function NpcData:GetDressParts() local parts = NSceneNpcProxy.Instance:GetOrCreatePartsFromStaticData(self.staticData) if(self.useServerDressData) then --魔物變身,使用userdata local userData = self.userdata if(userData~=nil) then local cloned = NpcData.super.GetDressParts(self) for k,v in pairs(cloned) do if(v==0) then cloned[k] = parts[k] end end return cloned end end return parts end function NpcData:Camp_SetIsInMyGuild(val) if(self.campHandler) then self.campHandler:SetIsSameGuild(val) self.campChanged = self.campHandler.dirty end end function NpcData:Camp_SetIsInGVG(val) if(self.campHandler) then self.campHandler:SetIsInGVGScene(val) self.campChanged = self.campHandler.dirty end end -- override begin function NpcData:IsImmuneSkill(skillID) local immuneSkills = self.staticData.ImmuneSkill if(immuneSkills and #immuneSkills>0) then return TableUtility.ArrayFindIndex(immuneSkills, skillID) > 0 end return false end function NpcData:IsFly() return nil ~= self.behaviourData and self.behaviourData:IsFly() end function NpcData:DamageAlways1() return nil ~= self.behaviourData and 0 < self.behaviourData:GetDamageAlways1() or false end function NpcData:SetOwnerID(serverData) self.ownerID = serverData.owner end function NpcData:DoConstruct(asArray, serverData) NpcData.super.DoConstruct(self,asArray,serverData) self.dressEnable = true self.id = serverData.id self.uniqueid = serverData.uniqueid self.name = serverData.name self.idleAction = serverData.waitaction == '' and nil or serverData.waitaction if(serverData.character and #serverData.character>0) then TableUtility.ArrayShallowCopy(self.charactors, serverData.character) end if(self.staticData==nil or self.staticData.id ~= serverData.npcID) then self.staticData = Table_Monster[serverData.npcID] if(self.staticData==nil) then self.staticData = Table_Npc[serverData.npcID] end if(self.staticData==nil) then errorLog(string.format("找不到Npc配置,%s",serverData.npcID)) LogUtility.InfoFormat("找不到Npc配置,{0}", serverData.npcID ) return end self.shape = self.staticData.Shape self.race = self.staticData.Race_Parsed self.detailedType = NpcData.NpcDetailedType[self.staticData.Type] end self.camp = RoleDefines_Camp.NEUTRAL local npcmonsterUtility = NpcMonsterUtility if(npcmonsterUtility.IsMonsterByData(self.staticData)) then self.type = NpcData.NpcType.Monster self.camp = RoleDefines_Camp.ENEMY elseif(npcmonsterUtility.IsPetByData(self.staticData))then self.type = NpcData.NpcType.Pet else self.type = NpcData.NpcType.Npc if(npcmonsterUtility.IsNpcByData(self.staticData))then self.camp = RoleDefines_Camp.NEUTRAL elseif(npcmonsterUtility.IsFriendNpcByData(self.staticData)) then self.camp = RoleDefines_Camp.FRIEND end --傭兵貓型別,陣營為友方 if(self.staticData.Type == "WeaponPet" or self.staticData.Type == "SkillNpc") then self.camp = RoleDefines_Camp.FRIEND end end if(serverData.guildid and serverData.guildid~=0) then self.campHandler = CampHandler.new(self.camp) TableUtility.ArrayClear(tempArray); tempArray[1] = serverData.guildid; tempArray[2] = serverData.guildname; tempArray[3] = serverData.guildicon; tempArray[4] = serverData.guildjob; self:SetGuildData(tempArray); end self.boss = self:IsBoss() self.mini = self:IsMini() or self:GetFeature_FakeMini() self.zoneType = self:GetZoneType() self:SetBehaviourData(serverData.behaviour) self.changelinepunish = self:GetFeature_ChangeLinePunish() --產生cullingid self:SpawnCullingID() self.bodyScale = self:GetDefaultScale() self.search = serverData.search self.searchrange = serverData.searchrange self:SetOwnerID(serverData) end function NpcData:DoDeconstruct(asArray) NpcData.super.DoDeconstruct(self,asArray) self.staticData = nil self.campHandler = nil self.useServerDressData = false TableUtility.ArrayClear(self.charactors) end -- override end