2025-06-04 05:02:57 +08:00

458 lines
11 KiB
Plaintext

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("<color=red>找不到Npc配置,{0}</color>", 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