📄 unpc.pas
字号:
// 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 + -