⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unpc.pas

📁 千年源代码,只缺少控件,可以做二次开发用,好不容易得来的
💻 PAS
📖 第 1 页 / 共 2 页
字号:
//                  Mon := TMonster (GetViewObjectById (SenderInfo.id));
//                  if Mon <> nil then begin
//                     tmpAttackSkill := Mon.GetAttackSkill;
//                     if tmpAttackSkill <> nil then begin
//                        if tmpAttackSkill.boAutoAttack = true then
//                           AttackSkill.SetTargetId (SenderInfo.id, true);
//                     end;
//                  end;
//               end;
//               exit;
            end;
            if pSelfData^.rboAutoAttack = true then begin
               if SenderInfo.Feature.rrace = RACE_HUMAN then begin
                  AttackSkill.SetTargetId (SenderInfo.id, true);
               end;
            end;
         end;
      FM_CHANGEFEATURE:
         begin
            if SenderInfo.id = BasicData.id then exit;
            if SenderInfo.Feature.rHideState = hs_0 then exit;
            if (SenderInfo.id = AttackSkill.GetTargetId)
               and (SenderInfo.Feature.rFeatureState = wfs_die) then begin
               AttackSkill.SetTargetId (0, true);
               exit;
            end;

            if AttackSkill.GetTargetID <> 0 then exit;

            if pSelfData^.rboAutoAttack = true then begin
               if SenderInfo.Feature.rrace = RACE_HUMAN then begin
                  AttackSkill.SetTargetId (SenderInfo.id, true);
               end;
            end;
         end;
      FM_STRUCTED :
         begin
            if SenderInfo.id = BasicData.id then begin
               if pSelfData^.rboProtector then begin
                  AttackSkill.SetTargetId (aSubData.attacker, true);
               end;
               if CurLife <= 0 then begin
                  BasicData.nx := BasicData.x;
                  BasicData.ny := BasicData.y;

                  AttackSkill.SetTargetId (0, true);

                  for i := 0 to 5 - 1 do begin
                     if pSelfData^.rHaveItem[i].rName <> '' then begin
                        if ItemClass.GetCheckItemData (NpcName, pSelfData^.rHaveItem[i], ItemData) = false then continue;
                        ItemData.rOwnerName[0] := 0;
                        SubData.ItemData := ItemData;
                        SubData.ServerId := Manager.ServerId;
                        Phone.SendMessage (MANAGERPHONE, FM_ADDITEM, BasicData, SubData);
                     end;
                  end;
               end;
            end;
         end;
      FM_DEADHIT :
         begin
            if SenderInfo.id = BasicData.id then exit;
            if BasicData.Feature.rfeaturestate = wfs_die then begin Result := PROC_TRUE; exit; end;
            CurLife := 0;

            AttackSkill.SetTargetId (0, true);

            BasicData.nx := BasicData.x;
            BasicData.ny := BasicData.y;
            for i := 0 to 5 - 1 do begin
               if pSelfData^.rHaveItem[i].rName <> '' then begin
                  if ItemClass.GetCheckItemData (NpcName, pSelfData^.rHaveItem[i], ItemData) = false then continue;
                  ItemData.rOwnerName[0] := 0;
                  SubData.ItemData := ItemData;
                  SubData.ServerId := Manager.ServerId;
                  Phone.SendMessage (MANAGERPHONE, FM_ADDITEM, BasicData, SubData);
               end;
            end;

            CommandChangeCharState (wfs_die);
         end;
      FM_SAY:
         begin
            if boFighterNpc then exit;
            if SenderInfo.Feature.rfeaturestate = wfs_die then exit;
            if SenderInfo.id = BasicData.id then exit;
            if SenderInfo.Feature.rrace = RACE_NPC then exit;
            str := GetWordString (aSubData.SayString);

            if BuySellSkill <> nil then begin
               if BuySellSkill.ProcessMessage (str, SenderInfo) = true then exit;
            end;
            if DeallerSkill <> nil then begin
               if DeallerSkill.ProcessMessage (str, SenderInfo) = true then exit;
            end;
         end;
   end;
end;

procedure TNpc.Update (CurTick: integer);
begin
//   inherited UpDate (CurTick);
   if boFighterNpc then exit;

   case LifeObjectState of
      los_init :
         begin
            Start;
         end;
      los_die :
         begin
            if CurTick > DiedTick + 1600 then begin
               if Manager.RegenInterval = 0 then begin
                  Regen;
               end else begin
                  FboAllowDelete := true;
               end;
            end;
         end;
      los_none:
         begin
            if SpeechSkill <> nil then SpeechSkill.ProcessMessage (CurTick);
            if AttackSkill <> nil then AttackSkill.ProcessNone (CurTick);
         end;
      los_attack:
         begin
            if AttackSkill <> nil then AttackSkill.ProcessAttack (CurTick, Self);
         end;
      los_moveattack :
         begin
            if AttackSkill <> nil then AttackSkill.ProcessMoveAttack (CurTick);
         end;
      los_deadattack :
         begin
            if AttackSkill <> nil then AttackSkill.ProcessDeadAttack (CurTick);
         end;
   end;
end;

function TNpc.GetAttackSkill : TAttackSkill;
begin
   if AttackSkill = nil then
      AttackSkill := TAttackSkill.Create (Self);
      
   Result := AttackSkill;
end;

procedure TNpc.SetAttackSkill (aAttackSkill : TAttackSkill);
begin
   if (AttackSkill <> nil) and (FboCopy = false) then begin
      AttackSkill.Free;
   end;

   AttackSkill := aAttackSkill;
end;

////////////////////////////////////////////////////
//
//             ===  NpcList  ===
//
////////////////////////////////////////////////////

constructor TNpcList.Create (cnt: integer; aManager: TManager);
begin
   Manager := aManager;
   CurProcessPos := 0;
   AnsList := TAnsList.Create (cnt, AllocFunction, FreeFunction);

   ReLoadFromFile;
end;

destructor TNpcList.Destroy;
begin
   Clear;
   AnsList.Free;
   inherited destroy;
end;

procedure TNpcList.Clear;
var
   i : Integer;
begin
   for i := AnsList.Count - 1 downto 0 do begin
      TNpc (AnsList[i]).EndProcess;
      TNpc (AnsList[i]).SetAttackSkill (nil);
      AnsList.Delete (i);
   end;
end;

procedure TNpcList.ReLoadFromFile;
var
   i, j, iCount, iMapID : integer;
   iName, NpcName : String;
   CreateNpcData : TCreateNpcData;
   NpcData : TNpcData;
   DB : TUserStringDB;
   FileName : String;
begin
   Clear;

   FileName := '.\Setting\CreateNpc' + IntToStr (Manager.ServerID) + '.SDB';

   if not FileExists (FileName) then exit;

   DB := TUserStringDb.Create;
   DB.LoadFromFile (FileName);

   for i := 0 to DB.Count - 1 do begin
      iName := DB.GetIndexName (i);
      if iName = '' then Continue;

      NpcName := DB.GetFieldValueString (iName, 'NpcName');
      if NpcName = '' then continue;
      NpcClass.GetNpcData (NpcName, @NpcData);
      if NpcData.rName[0] = 0 then continue;
      iCount := DB.GetFieldValueInteger (iName, 'Count');
      if iCount <= 0 then continue;

      CreateNpcData.Name := NpcName;
      CreateNpcData.X := DB.GetFieldValueInteger (iName, 'X');
      CreateNpcData.Y := DB.GetFieldValueInteger (iName, 'Y');
      CreateNpcData.Width := DB.GetFieldValueInteger (iName, 'Width');
      CreateNpcData.BookName := DB.GetFieldValueString (iName, 'BookName');

      for j := 0 to iCount - 1 do begin
         AddNpc (CreateNpcData.Name, CreateNpcData.x, CreateNpcData.y, CreateNpcData.Width, CreateNpcData.BookName);
      end;
   end;
   DB.Free;
end;

function  TNpcList.GetCount: integer;
begin
   Result := AnsList.Count;
end;

function TNpcList.AllocFunction: pointer;
begin
   Result := TNpc.Create;
end;

procedure TNpcList.FreeFunction (item: pointer);
begin
   TNpc (item).Free;
end;

procedure TNpcList.AddNpc (aNpcName: string; ax, ay, aw: integer; aBookName : String);
var
   Npc : TNpc;
begin
   Npc := AnsList.GetUnUsedPointer;
   if Npc <> nil then begin
      Npc.SetManagerClass (Manager);
      Npc.Initial (aNpcName, ax, ay, aw, aBookName);
      AnsList.Add (Npc);
   end;
end;

function TNpcList.CallNpc (aNpcName: string; ax, ay, aw: integer; aName : String) : TNpc;
var
   Npc : TNpc;
   AttackSkill : TAttackSkill;
begin
   Result := nil;
   
   Npc := AnsList.GetUnUsedPointer;
   if Npc <> nil then begin
      Npc.SetManagerClass (Manager);
      Npc.Initial (aNpcName, ax, ay, aw, '');
      Npc.Start;
      AttackSkill := Npc.GetAttackSkill;
      if AttackSkill <> nil then begin
         AttackSkill.SetDeadAttackName (aName);
      end;
      AnsList.Add (Npc);

      Result := Npc;
   end;
end;

procedure TNpcList.Update (CurTick: integer);
var
   i : integer;
   Npc : TNpc;
begin
   for i := 0 to ProcessListCount-1 do begin
      if AnsList.Count = 0 then break;
      if CurProcessPos >= AnsList.Count then CurProcessPos := 0;
      Npc := AnsList[CurProcessPos];
      if Npc.FboAllowDelete = true then begin
         Npc.EndProcess;
         Npc.SetAttackSkill (nil);
         AnsList.Delete (CurProcessPos);
      end else begin
         try
            Npc.Update (CurTick);
            Inc (CurProcessPos);
         except
            Npc.FboAllowDelete := true;
            frmMain.WriteLogInfo (format ('TNpcList.Update (%s) failed', [Npc.NpcName]));
         end;
      end;
   end;
end;

function TNpcList.GetNpcByName (aName : String) : TBasicObject;
var
   i : Integer;
   BO : TBasicObject;
begin
   Result := nil;
   for i := 0 to AnsList.Count - 1 do begin
      BO := AnsList[i];
      if BO <> nil then begin
         if StrPas (@BO.BasicData.Name) = aName then begin
            if BO.BasicData.Feature.rfeaturestate <> wfs_die then begin
               Result := BO;
               exit;
            end;
         end;
      end;
   end;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -