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

📄 objplaymon.pas

📁 FIR引擎最新源码+注册
💻 PAS
📖 第 1 页 / 共 5 页
字号:
{人形怪物 分身}

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 + -