📄 umonster.pas
字号:
unit uMonster;
interface
uses
Windows, Classes, SysUtils, svClass,subutil, uAnsTick, AnsUnit,
BasicObj, FieldMsg, MapUnit, DefType, Autil32, aiunit, uUser,
uAIPath, uManager, uSkills, UserSDB;
type
TMonster = class (TLifeObject)
private
pSelfData : PTMonsterData;
HaveItem : array[0..5 - 1] of TCheckItem;
AttackSkill : TAttackSkill;
procedure SetAttackSkillData;
protected
procedure SetMonsterData;
function FieldProc (hfu: Longint; Msg: word; var SenderInfo: TBasicData; var aSubData: TSubData): Integer; override;
procedure Initial (aMonsterName: string; ax, ay, aw: integer);
procedure StartProcess; override;
procedure EndProcess; override;
function Regen : Boolean;
function Start : Boolean;
public
MonsterName : String;
constructor Create;
destructor Destroy; override;
procedure Update (CurTick: integer); override;
procedure CallMe(x, y : Integer);
function GetAttackSkill : TAttackSkill;
procedure SetAttackSkill (aAttackSkill : TAttackSkill);
end;
TMonsterList = class
private
Manager : TManager;
CurProcessPos : integer;
AnsList : TAnsList;
function AllocFunction: pointer;
procedure FreeFunction (item: pointer);
function GetCount: integer;
procedure Clear;
public
constructor Create (cnt: integer; aManager : TManager);
destructor Destroy; override;
procedure AddMonster (aMonsterName: string; ax, ay, aw: integer; aMemberStr : String);
function CallMonster (aMonsterName: string; ax, ay, aw: integer; aName : String) : TMonster;
function CopyMonster (aBasicData : TBasicData; aAttackSkill : TAttackSkill) : TMonster;
procedure ReLoadFromFile;
procedure Update (CurTick: integer);
function GetMonsterByName(aName : String) : TMonster;
property Count : integer read GetCount;
end;
implementation
uses
SvMain;
/////////////////////////////////////
// Monster
////////////////////////////////////
constructor TMonster.Create;
begin
inherited Create;
pSelfData := nil;
AttackSkill := nil;
end;
destructor TMonster.Destroy;
begin
pSelfData := nil;
if (AttackSkill <> nil) and (FboCopy = false) then begin
AttackSkill.Free;
end;
inherited destroy;
end;
function TMonster.Regen : Boolean;
var
xx, yy : Integer;
begin
Result := true;
{
for i := 0 to 10 - 1 do begin
xx := CreatedX - ActionWidth + Random(ActionWidth * 2);
yy := CreatedY - ActionWidth + Random(ActionWidth * 2);
if Maper.isMoveable (xx, yy) then begin
EndProcess;
BasicData.x := xx;
BasicData.y := yy;
BasicData.nx := xx;
BasicData.ny := yy;
BasicData.Feature.rHitMotion := AM_HIT1;
StartProcess;
exit;
end;
end;
}
xx := CreatedX - ActionWidth + Random(ActionWidth * 2);
yy := CreatedY - ActionWidth + Random(ActionWidth * 2);
if Maper.GetMoveableXY (xx, yy, 10) then begin
EndProcess;
BasicData.x := xx;
BasicData.y := yy;
BasicData.nx := xx;
BasicData.ny := yy;
BasicData.Feature.rHitMotion := AM_HIT1;
StartProcess;
exit;
end;
Result := false;
end;
function TMonster.Start : Boolean;
var
xx, yy : Integer;
begin
Result := true;
{
for i := 0 to 10 - 1 do begin
xx := CreatedX - ActionWidth + Random(ActionWidth * 2);
yy := CreatedY - ActionWidth + Random(ActionWidth * 2);
if Maper.isMoveable (xx, yy) then begin
BasicData.x := xx;
BasicData.y := yy;
BasicData.nx := xx;
BasicData.ny := yy;
BasicData.Feature.rHitMotion := AM_HIT1;
StartProcess;
exit;
end;
end;
}
xx := CreatedX - ActionWidth + Random(ActionWidth * 2);
yy := CreatedY - ActionWidth + Random(ActionWidth * 2);
if Maper.GetMoveableXY (xx, yy, 10) then begin
BasicData.x := xx;
BasicData.y := yy;
BasicData.nx := xx;
BasicData.ny := yy;
BasicData.Feature.rHitMotion := AM_HIT1;
StartProcess;
exit;
end;
Result := false;
end;
procedure TMonster.SetAttackSkillData;
begin
if pSelfData = nil then exit;
if AttackSkill = nil then exit;
AttackSkill.boViewHuman := pSelfData^.rboViewHuman;
AttackSkill.boAutoAttack := pSelfData^.rboAutoAttack;
AttackSkill.EscapeLife := pSelfData^.rEscapeLife;
AttackSkill.ViewWidth := pSelfData^.rViewWidth;
AttackSkill.boChangeTarget := pSelfData^.rboChangeTarget;
AttackSkill.boBoss := pSelfData^.rboBoss;
AttackSkill.boVassal := pSelfData^.rboVassal;
AttackSkill.VassalCount := pSelfData^.rVassalCount;
if (pSelfData^.rAttackMagic.rFunction >= 4)
and (pSelfData^.rAttackMagic.rFunction <= 6) then begin
HaveSkill := pSelfData^.rAttackMagic.rFunction;
end else begin
AttackSkill.SetAttackMagic (pSelfData^.rAttackMagic);
end;
end;
procedure TMonster.SetMonsterData;
var
i : Integer;
begin
if pSelfData = nil then exit;
LifeData.damageBody := LifeData.damageBody + pSelfData^.rDamage;
LifeData.damageHead := LifeData.damageHead + 0;
LifeData.damageArm := LifeData.damageArm + 0;
LifeData.damageLeg := LifeData.damageLeg + 0;
LifeData.AttackSpeed := LifeData.AttackSpeed + pSelfData^.rAttackSpeed;
LifeData.avoid := LifeData.avoid + pSelfData^.ravoid;
LifeData.recovery := LifeData.recovery + pSelfData^.rrecovery;
LifeData.armorBody := LifeData.armorBody + pSelfData^.rarmor;
LifeData.armorHead := LifeData.armorHead + pSelfData^.rarmor;
LifeData.armorArm := LifeData.armorArm + pSelfData^.rarmor;
LifeData.armorLeg := LifeData.armorLeg + pSelfData^.rarmor;
BasicData.Feature.raninumber := pSelfData^.rAnimate;
BasicData.Feature.rImageNumber := pSelfData^.rShape;
for i := 0 to 5 - 1 do begin
HaveItem[i] := pSelfData^.rHaveItem[i];
end;
MaxLife := pSelfData^.rLife;
SetAttackSkillData;
WalkSpeed := pSelfData^.rWalkSpeed;
SoundNormal := pSelfData^.rSoundNormal;
SoundAttack := pSelfData^.rSoundAttack;
SoundDie := pSelfData^.rSoundDie;
SoundStructed := pSelfData^.rSoundStructed;
end;
procedure TMonster.Initial (aMonsterName: string; ax, ay, aw: Integer);
var
MonsterData : TMonsterData;
begin
inherited Initial (aMonsterName);
if AttackSkill = nil then begin
AttackSkill := TAttackSkill.Create (Self);
end;
pSelfData := MonsterClass.GetMonsterDataPointer (aMonsterName);
SetMonsterData;
MonsterName := aMonsterName;
Basicdata.id := GetNewMonsterId;
BasicData.ClassKind := CLASS_MONSTER;
BasicData.Feature.rrace := RACE_MONSTER;
CreatedX := ax;
CreatedY := ay;
ActionWidth := aw;
end;
procedure TMonster.StartProcess;
var
SubData : TSubData;
MonsterData : TMonsterData;
begin
inherited StartProcess;
CurLife := MaxLife;
if AttackSkill = nil then begin
AttackSkill := TAttackSkill.Create (Self);
AttackSkill.TargetX := CreateX - 3 + Random (6);
AttackSkill.TargetY := CreateY - 3 + Random (6);
SetAttackSkillData;
end;
Phone.RegisterUser (BasicData.id, FieldProc, BasicData.X, BasicData.Y);
Phone.SendMessage (0, FM_CREATE, BasicData, SubData);
if FboCopy = true then begin
ShowEffect (1, lek_none);
end;
end;
procedure TMonster.EndProcess;
var
SubData : TSubData;
begin
if FboRegisted = FALSE then exit;
SetAttackSkill (nil);
FboCopy := false;
Phone.SendMessage (0, FM_DESTROY, BasicData, SubData);
Phone.UnRegisterUser (BasicData.id, BasicData.x, BasicData.y);
inherited EndProcess;
end;
procedure TMonster.CallMe(x, y : Integer);
begin
EndProcess;
BasicData.x := x;
BasicData.y := y;
StartProcess;
end;
function TMonster.FieldProc (hfu: Longint; Msg: word; var SenderInfo: TBasicData; var aSubData: TSubData): Integer;
var
i : Integer;
tx, ty, len, len2: word;
bo : TBasicObject;
SubData : TSubData;
ItemData : TItemData;
label abcde;
begin
Result := PROC_FALSE;
if isRangeMessage ( hfu, Msg, SenderInfo) = FALSE then exit;
Result := inherited FieldProc (hfu, Msg, Senderinfo, aSubData);
if Result = PROC_TRUE then exit;
case Msg of
FM_HIT, FM_STRUCTED, FM_CHANGEFEATURE, FM_MOVE, FM_SHOW:
begin
if SenderInfo.id = BasicData.id then goto abcde;
if SenderInfo.Feature.rrace <> RACE_HUMAN then goto abcde; // 林籍捞搁 阁胶磐档 傍拜
if SenderInfo.Feature.rHideState = hs_0 then goto abcde;
if (SenderInfo.Feature.rFeatureState = wfs_die) then begin
if SenderInfo.id = AttackSkill.CurNearViewHumanId then AttackSkill.CurNearViewHumanId := 0;
if SenderInfo.id = AttackSkill.HateHumanId then AttackSkill.HateHumanId := 0;
goto abcde;
end;
len := GetLargeLength (BasicData.x, BasicData.y, SenderInfo.x, SenderInfo.y);
if AttackSkill.ViewWidth < len then exit;
if AttackSkill.boViewHuman = FALSE then exit;
bo := nil;
if AttackSkill.CurNearViewHumanID <> 0 then
bo := TBasicObject (GetViewObjectById (AttackSkill.CurNearViewHumanId));
if bo <> nil then begin
len2 := GetLargeLength (BasicData.x, BasicData.y, bo.Posx, bo.Posy);
if len2 > len then AttackSkill.CurNearViewHumanId := SenderInfo.id;
end else AttackSkill.CurNearViewHumanId := SenderInfo.id;
end;
FM_HIDE :
begin
if SenderInfo.id = BasicData.id then goto abcde;
if SenderInfo.id = AttackSkill.CurNearViewHumanId then AttackSkill.CurNearViewHumanId := 0;
if SenderInfo.id = AttackSkill.HateHumanId then AttackSkill.HateHumanId := 0;
end;
end;
abcde:
case Msg of
FM_SHOW :
begin
end;
FM_CHANGEFEATURE:
begin
end;
FM_GATHERVASSAL :
begin
if SenderInfo.id = BasicData.id then exit;
if AttackSkill.boVassal and (LifeObjectState = los_none) and (aSubData.VassalCount > 0) then begin
aSubData.VassalCount := aSubData.VassalCount - 1;
AttackSkill.SetTargetId (aSubData.TargetId, false);
end;
end;
FM_STRUCTED :
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -