📄 objplaymon.pas
字号:
{人形怪物 分身}
unit ObjPlayMon;
interface
uses
Windows, SysUtils, StrUtils, Classes, Grobal2, ObjBase, IniFiles;
type
TPlayMonster = class(TBaseObject)
n54C: Integer;
m_dwThinkTick: LongWord;
bo554: Boolean;
m_boDupMode: Boolean;
m_nNotProcessCount: Integer; //未被处理次数,用于怪物处理循环
m_nTargetX: Integer;
m_nTargetY: Integer;
m_boRunAwayMode: Boolean;
m_dwRunAwayStart: LongWord;
m_dwRunAwayTime: LongWord;
m_boCanPickUpItem: Boolean;
m_boSlavePickUpItem: Boolean;
m_dwPickUpItemTick: LongWord;
m_boPickUpItemOK: Boolean;
m_nPickUpItemMakeIndex: Integer;
m_wHitMode: Word;
m_dwAutoAvoidTick: LongWord; //自动躲避间隔
m_boAutoAvoid: Boolean; //是否躲避
m_boDoSpellMagic: Boolean; //是否可以使用魔法
m_dwDoSpellMagicTick: LongWord; //使用魔法间隔
m_boGotoTargetXY: Boolean;
m_SkillShieldTick: LongWord; //魔法盾使用间隔
m_SkillBigHealling: LongWord; //群体治疗术使用间隔
m_SkillDejiwonho: LongWord; //神圣战甲术使用间隔
m_dwCheckDoSpellMagic: LongWord;
m_nDieDropUseItemRate: Integer; //死亡掉装备几率
wSkill_01: Word; //雷电术
wSkill_02: Word; //地狱雷光
wSkill_03: Word; //冰咆哮
wSkill_04: Word; //火龙气焰
wSkill_05: Word; //魔法盾
wSkill_06: Word; //施毒术
wSkill_07: Word; //灵魂火符
wSkill_08: Word; //神圣战甲术
wSkill_09: Word; //群体治疗术
wSkill_10: Word; //群体施毒术
wSkill_11: Word; //烈火剑法
wSkill_12: Word; //刺杀剑法
wSkill_13: Word; //半月弯刀
private
function Think: Boolean;
function GetSpellPoint(UserMagic: pTUserMagic): Integer;
function AllowFireHitSkill(): Boolean; {烈火}
function DoSpellMagic(wMagIdx: Word): Boolean;
procedure SearchPickUpItem(dwSearchTime: LongWord);
procedure EatMedicine();
function WarrAttackTarget(wHitMode: Word): Boolean; {物理攻击}
function WarrorAttackTarget(): Boolean; {战士攻击}
function WizardAttackTarget(): Boolean; {法师攻击}
function TaoistAttackTarget(): Boolean; {道士攻击}
function EatUseItems(btItemType: Byte): Boolean; {自动吃药}
function AutoAvoid(): Boolean; //自动躲避
function SearchPickUpItemOK(): Boolean;
function IsPickUpItem(StdItem: pTStdItem): Boolean;
function WalkToTargetXY(nTargetX, nTargetY: Integer): Boolean;
function CheckSlaveTarget(TargetObject: TBaseObject): Boolean; //检测是否是其他宝宝的目标
function CheckSlavePickUpItem(): Boolean; //检测其他宝宝是不是正在拣物品
function StartAutoAvoid(): Boolean;
function CheckUserMagic(wMagIdx: Word): Integer;
function CheckTargetXYCount(nX, nY, nRange: Integer): Integer;
function AllowGotoTargetXY(): Boolean;
procedure GotoTargetXYRange();
function GetUserItemList(nItemType: Integer): Integer;
function UseItem(nItemType, nIndex: Integer): Boolean;
function CheckUserItemType(nItemType: Integer): Boolean;
function CheckItemType(nItemType: Integer; StdItem: pTStdItem): Boolean;
function CheckDoSpellMagic(): Boolean;
function CheckTakeOnItems(nWhere: Integer; var StdItem: TStdItem): Boolean;
function FindMagic(sMagicName: string): pTUserMagic;
function CheckTargetXYCountOfDirection(nX, nY, nDir, nRange: Integer): Integer;
public
constructor Create(); override;
destructor Destroy; override;
function Operate(ProcessMsg: pTProcessMessage): Boolean; override;
function AttackTarget(): Boolean;
function AddItems(UserItem: pTUserItem; btWhere: Integer): Boolean; //获取身上装备
procedure Run; override;
procedure SearchTarget();
procedure DelTargetCreat(); override;
procedure SetTargetXY(nX, nY: Integer); virtual;
procedure GotoTargetXY(nTargetX, nTargetY: Integer); virtual;
procedure Wondering(); virtual;
procedure Attack(TargeTBaseObject: TBaseObject; nDir: Integer); virtual;
procedure Struck(hiter: TBaseObject); virtual;
procedure AddItemsFromConfig();
procedure InitializeMonster;
end;
implementation
uses UsrEngn, M2Share, Event, Envir, Magic, HUtil32;
{ TPlayMonster }
constructor TPlayMonster.Create;
begin
inherited;
m_boDupMode := False;
bo554 := False;
m_dwThinkTick := GetTickCount();
m_nViewRange := 10;
m_nRunTime := 250;
//m_dwSearchTime := 3000 + Random(2000);
m_dwSearchTick := GetTickCount();
m_btRaceServer := RC_PLAYMOSTER;
m_nCopyHumanLevel := 2;
m_nNotProcessCount := 0;
m_nTargetX := -1;
dwTick3F0 := Random(4) * 500 + 1000;
dwTick3F4 := GetTickCount();
m_dwHitTick := GetTickCount - LongWord(Random(3000));
m_dwWalkTick := GetTickCount - LongWord(Random(3000));
m_nWalkSpeed := 300;
m_nWalkStep := 10;
m_dwWalkWait := 0;
m_dwSearchEnemyTick := GetTickCount();
m_boRunAwayMode := False;
m_dwRunAwayStart := GetTickCount();
m_dwRunAwayTime := 0;
m_boCanPickUpItem := True;
m_boSlavePickUpItem := False;
m_dwPickUpItemTick := GetTickCount();
m_boPickUpItemOK := True;
m_dwAutoAvoidTick := GetTickCount(); //自动躲避间隔
m_boAutoAvoid := True; //是否躲避
m_boDoSpellMagic := True; //是否使用魔法
m_boGotoTargetXY := True; //是否走向目标
m_nNextHitTime := 300;
m_dwDoSpellMagicTick := GetTickCount(); //使用魔法间隔
m_SkillShieldTick := GetTickCount(); //魔法盾使用魔法间隔
m_SkillBigHealling := GetTickCount(); //群体治疗术使用间隔
m_SkillDejiwonho := GetTickCount(); //神圣战甲术使用间隔
m_dwCheckDoSpellMagic := GetTickCount();
m_nDieDropUseItemRate := 100;
end;
destructor TPlayMonster.Destroy;
begin
inherited;
end;
procedure TPlayMonster.InitializeMonster;
var
I: Integer;
begin
AddItemsFromConfig();
case m_btJob of
0: begin
wSkill_11 := CheckUserMagic(SKILL_FIRESWORD); //烈火剑法
wSkill_12 := CheckUserMagic(SKILL_ERGUM); //刺杀剑法
wSkill_13 := CheckUserMagic(SKILL_BANWOL); //半月弯刀
end;
1: begin
wSkill_01 := CheckUserMagic(SKILL_LIGHTENING); //雷电术
wSkill_02 := CheckUserMagic(SKILL_LIGHTFLOWER); //地狱雷光
wSkill_03 := CheckUserMagic(SKILL_SNOWWIND); //冰咆哮
wSkill_04 := CheckUserMagic(SKILL_47); //火龙气焰
wSkill_05 := CheckUserMagic(SKILL_SHIELD); //魔法盾
if (wSkill_01 = 0) and (wSkill_02 = 0) and (wSkill_03 = 0) and (wSkill_04 = 0) then m_boDoSpellMagic := False;
end;
2: begin
wSkill_06 := CheckUserMagic(SKILL_AMYOUNSUL); //施毒术
wSkill_07 := CheckUserMagic(SKILL_FIRECHARM); //灵魂火符
wSkill_08 := CheckUserMagic(SKILL_DEJIWONHO); //神圣战甲术
wSkill_09 := CheckUserMagic(SKILL_BIGHEALLING); //群体治疗术
wSkill_10 := CheckUserMagic(SKILL_GROUPAMYOUNSUL); //群体施毒术
if (wSkill_06 = 0) and (wSkill_07 = 0) and (wSkill_10 = 0) then m_boDoSpellMagic := False;
end;
end;
end;
procedure TPlayMonster.GotoTargetXY(nTargetX, nTargetY: Integer);
var
I: Integer;
nDir: Integer;
n10: Integer;
n14: Integer;
n20: Integer;
nOldX: Integer;
nOldY: Integer;
n16: Integer;
begin
if ((m_nCurrX <> nTargetX) or (m_nCurrY <> nTargetY)) then begin
n10 := nTargetX;
n14 := nTargetY;
dwTick3F4 := GetTickCount();
nDir := DR_DOWN;
if n10 > m_nCurrX then begin
nDir := DR_RIGHT;
if n14 > m_nCurrY then nDir := DR_DOWNRIGHT;
if n14 < m_nCurrY then nDir := DR_UPRIGHT;
end else begin
if n10 < m_nCurrX then begin
nDir := DR_LEFT;
if n14 > m_nCurrY then nDir := DR_DOWNLEFT;
if n14 < m_nCurrY then nDir := DR_UPLEFT;
end else begin
if n14 > m_nCurrY then nDir := DR_DOWN
else if n14 < m_nCurrY then nDir := DR_UP;
end;
end;
nOldX := m_nCurrX;
nOldY := m_nCurrY;
if (abs(m_nCurrX - nTargetX) >= 3) or (abs(m_nCurrY - nTargetY) >= 3) then begin
if not RunTo(nDir, False, nTargetX, nTargetY) then begin
WalkTo(nDir, False);
n20 := Random(3);
for I := DR_UP to DR_UPLEFT do begin
if (nOldX = m_nCurrX) and (nOldY = m_nCurrY) then begin
if n20 <> 0 then Inc(nDir)
else if nDir > 0 then Dec(nDir)
else nDir := DR_UPLEFT;
if (nDir > DR_UPLEFT) then nDir := DR_UP;
WalkTo(nDir, False);
end;
end;
end;
end else begin
WalkTo(nDir, False);
n20 := Random(3);
for I := DR_UP to DR_UPLEFT do begin
if (nOldX = m_nCurrX) and (nOldY = m_nCurrY) then begin
if n20 <> 0 then Inc(nDir)
else if nDir > 0 then Dec(nDir)
else nDir := DR_UPLEFT;
if (nDir > DR_UPLEFT) then nDir := DR_UP;
WalkTo(nDir, False);
end;
end;
end;
end;
end;
function TPlayMonster.WalkToTargetXY(nTargetX, nTargetY: Integer): Boolean;
var
I: Integer;
nDir: Integer;
n10: Integer;
n14: Integer;
n20: Integer;
nOldX: Integer;
nOldY: Integer;
n16: Integer;
begin
Result := False;
if ((m_nCurrX <> nTargetX) or (m_nCurrY <> nTargetY)) then begin
n10 := nTargetX;
n14 := nTargetY;
dwTick3F4 := GetTickCount();
nDir := DR_DOWN;
if n10 > m_nCurrX then begin
nDir := DR_RIGHT;
if n14 > m_nCurrY then nDir := DR_DOWNRIGHT;
if n14 < m_nCurrY then nDir := DR_UPRIGHT;
end else begin
if n10 < m_nCurrX then begin
nDir := DR_LEFT;
if n14 > m_nCurrY then nDir := DR_DOWNLEFT;
if n14 < m_nCurrY then nDir := DR_UPLEFT;
end else begin
if n14 > m_nCurrY then nDir := DR_DOWN
else if n14 < m_nCurrY then nDir := DR_UP;
end;
end;
nOldX := m_nCurrX;
nOldY := m_nCurrY;
WalkTo(nDir, False);
if (nTargetX = m_nCurrX) and (nTargetY = m_nCurrY) then Result := True;
if not Result then begin
n20 := Random(3);
for I := DR_UP to DR_UPLEFT do begin
if (nOldX = m_nCurrX) and (nOldY = m_nCurrY) then begin
if n20 <> 0 then Inc(nDir)
else if nDir > 0 then Dec(nDir)
else nDir := DR_UPLEFT;
if (nDir > DR_UPLEFT) then nDir := DR_UP;
WalkTo(nDir, False);
if (nTargetX = m_nCurrX) and (nTargetY = m_nCurrY) then begin
Result := True;
Break;
end;
end;
end;
end;
end;
end;
function TPlayMonster.Operate(ProcessMsg: pTProcessMessage): Boolean;
begin
// Result:=False;
if ProcessMsg.wIdent = RM_STRUCK then begin
if (ProcessMsg.BaseObject = Self) and (TBaseObject(ProcessMsg.nParam3 {AttackBaseObject}) <> nil) then begin
SetLastHiter(TBaseObject(ProcessMsg.nParam3 {AttackBaseObject}));
Struck(TBaseObject(ProcessMsg.nParam3 {AttackBaseObject})); {0FFEC}
BreakHolySeizeMode();
if (m_Master <> nil) and
(TBaseObject(ProcessMsg.nParam3) <> m_Master) and
(TBaseObject(ProcessMsg.nParam3).m_btRaceServer = RC_PLAYOBJECT) then begin
m_Master.SetPKFlag(TBaseObject(ProcessMsg.nParam3));
end;
if g_Config.boMonSayMsg then MonsterSayMsg(TBaseObject(ProcessMsg.nParam3), s_UnderFire);
end;
Result := True;
end else begin
Result := inherited Operate(ProcessMsg);
end;
end;
procedure TPlayMonster.Struck(hiter: TBaseObject);
var
btDir: Byte;
begin
m_dwStruckTick := GetTickCount;
if hiter <> nil then begin
if (m_TargetCret = nil) or GetAttackDir(m_TargetCret, btDir) or (Random(6) = 0) then begin
if IsProperTarget(hiter) then
SetTargetCreat(hiter);
end;
end;
if m_boAnimal then begin
m_nMeatQuality := m_nMeatQuality - Random(300);
if m_nMeatQuality < 0 then m_nMeatQuality := 0;
end;
//if m_Abil.Level < 50 then
m_dwHitTick := m_dwHitTick + LongWord(150 - _MIN(130, m_Abil.Level * 4));
//WalkTime := WalkTime + (300 - _MIN(200, (Abil.Level div 5) * 20));
end;
procedure TPlayMonster.Attack(TargeTBaseObject: TBaseObject; nDir: Integer);
begin
inherited AttackDir(TargeTBaseObject, m_wHitMode, nDir);
end;
procedure TPlayMonster.DelTargetCreat;
begin
inherited;
m_nTargetX := -1;
m_nTargetY := -1;
end;
function TPlayMonster.CheckSlaveTarget(TargetObject: TBaseObject): Boolean;
var
I: Integer;
begin
Result := False;
if m_Master <> nil then begin
for I := 0 to m_Master.m_SlaveList.Count - 1 do begin
if TBaseObject(m_Master.m_SlaveList.Items[I]).m_TargetCret = TargetObject then begin
Result := True;
Break;
end;
end;
end;
end;
function TPlayMonster.CheckSlavePickUpItem(): Boolean;
var
I: Integer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -