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

📄 objmon3.pas

📁 传奇源代码的delphi版本
💻 PAS
📖 第 1 页 / 共 5 页
字号:
      if (GetTickCount - m_dwWalkWaitTick) > m_dwWalkWait then begin
        m_boWalkWaitLocked:=False;
      end;
    end;

    //if we are walkwaitlocked then just exit :p
    if m_boWalkWaitLocked then begin
      inherited;
      exit;
    end;

    if m_Master <> nil then begin
      //if m_TargetCret = nil then begin //if we have no target follow our master
        m_Master.GetBackPosition(nX,nY);
        if (abs(m_nTargetX - nX) > 0) or (abs(m_nTargetY - nY{nX}) > 0) then begin //004A922D
          m_nTargetX:=nX;
          m_nTargetY:=nY;
          if (abs(m_nCurrX - nX) <= 1) and (abs(m_nCurrY - nY) <= 1) then begin
            if m_PEnvir.GetMovingObject(nX,nY,True) <> nil then begin  //if there is already an 'object' behind our master then dont try to go to him
              m_nTargetX:=m_nCurrX;
              m_nTargetY:=m_nCurrY;
            end //004A92A5
          end;
        end; //004A92A5
      //end; //004A92A5 if m_TargetCret = nil then begin
      if (not m_Master.m_boSlaveRelax) and
             ((m_PEnvir <> m_Master.m_PEnvir) or
             (abs(m_nCurrX-m_Master.m_nCurrX) > 20) or
             (abs(m_nCurrY-m_Master.m_nCurrY) > 20)) then begin //if slave isnt set to rest and the master is out of our normal walking range teleport to him
        SpaceMove(m_Master.m_PEnvir.sMapName, m_nTargetX, m_nTargetY, 1);
      end; // 004A937E
    end;// 004A937E if m_Master <> nil then begin


    if (m_Master <> nil) and m_Master.m_boSlaveRelax then begin
      //if we have a master and he set petmode to rest then the pet should do absolutely nothing
      inherited ;
      exit;
    end;

    if m_nTargetX <> -1 then begin // if we have targetcoords to go towards then go there (or stay there if coords are same as where you are atm)
        // this locks the walkwaitlock after m_nwalkstep  amount of steps
      if not m_boWalkWaitLocked and (GetCurrentTime - m_dwWalkTick > GetWalkSpeed) then begin
        m_dwWalkTick:=GetCurrentTime;
        GotoTargetXY(); //004A93B5 0FFEF
        Inc(m_nWalkCount);
        if m_nWalkCount > m_nWalkStep then begin
          m_nWalkCount:=0;
          m_boWalkWaitLocked:=True;
          m_dwWalkWaitTick:=GetTickCount();
        end; //004A9151
      end;                              

    end else begin //if there's no targetcoords and no real target to attack then walk arround @ random
      if m_TargetCret = nil then Wondering();// FFEE   //Jacky
    end;

    if (m_TargetCret <> nil) and (GetCurrentTime - m_dwHitTick > GetHitSpeed * 3) then begin
      if (abs(m_nCurrX - m_TargetCret.m_nCurrX) <= 10) and (abs(m_nCurrY - m_TargetCret.m_nCurrY) <= 10) then begin
        m_dwHitTick:=GetCurrentTime;
        MagicAttack();
      end;
    end;

  end;

  inherited;
end;

procedure TClone.MagicAttack();
var
  nPower:Integer;
  UserMagic     :pTUserMagic;
  MirrorMagic   :pTUserMagic;
begin
  nPower:=0;
  if (m_Master <> nil) and (m_TargetCret <> nil) then
    m_Master.DamageSpell(10);//gues this needs to be configurable but for now i'm trying to get this working and dont know how it should work :p
    m_Master.HealthSpellChanged();
  if IsProperTarget (m_TargetCret) then begin
    UserMagic:=GetMagicInfo(11);
    MirrorMagic:=GetMagicInfo(SKILL_MIRROR);
    if (UserMagic = nil) or (MirrorMagic = nil) then exit;

    SendRefMsg(RM_SPELL,UserMagic.MagicInfo.btEffect,m_TargetCret.m_nCurrX,m_TargetCret.m_nCurrY,UserMagic.MagicInfo.wMagicId,'');

    if (Random(50) >= m_TargetCret.m_nAntiMagic) and (Random(9) <= MirrorMagic.btLevel * 3) then begin
      nPower:= GetPower(Mpow(UserMagic),UserMagic) + GetPower(Mpow(MirrorMagic),MirrorMagic);
      if m_TargetCret.m_btLifeAttrib = LA_UNDEAD then nPower:=ROUND(nPower * 1.5);
    end;
    
     SendRefMsg(RM_MAGICFIRE,0,MakeWord(UserMagic.MagicInfo.btEffectType,UserMagic.MagicInfo.btEffect), MakeLong(m_TargetCret.m_nCurrX,m_TargetCret.m_nCurrY),Integer(m_TargetCret),'');
     SendDelayMsg(self,RM_DELAYMAGIC,nPower,MakeLong(m_TargetCret.m_nCurrX,m_TargetCret.m_nCurrY),2,Integer(m_TargetCret),'',600);
  end;
end;

function TClone.MPow(UserMagic:pTUserMagic):Integer; //004921C8
begin
  Result:=UserMagic.MagicInfo.wPower + Random(UserMagic.MagicInfo.wMaxPower - UserMagic.MagicInfo.wPower);
end;

function TClone.GetPower(nPower:Integer;UserMagic:pTUserMagic):Integer;
var
nCPower:Integer;
begin
  Result:=0;
  //Safe check so you don't have any negitive one hit kills.
  nCPower:=ROUND(nPower / (UserMagic.MagicInfo.btTrainLv + 1) * (UserMagic.btLevel + 1)) + (UserMagic.MagicInfo.btDefPower + Random(UserMagic.MagicInfo.btDefMaxPower - UserMagic.MagicInfo.btDefPower));
  if nCPower > 0 then Result:=nCPower;
end;

procedure TClone.FindTarget();
begin
  if m_TargetCret <> nil then begin //check if our old target is still valid
    if (m_TargetCret.m_PEnvir <> m_PEnvir) or (m_TargetCret.m_boDeath) or (m_TargetCret.m_boGhost) then
      m_TargetCret := nil;
  end;

  if (m_LastHiter <> nil) and (m_TargetCret = nil) and (ispropertarget(m_LastHiter)) then begin //if we get attacked
    m_TargetCret := m_LastHiter;
  end;

  if m_Master.m_TargetCret <> nil then begin // if our master has a target
    if (m_Master.m_TargetCret.m_PEnvir = m_PEnvir) and (ispropertarget(m_Master.m_TargetCret)) then //if the target is on same map as us
      m_TargetCret := m_Master.m_TargetCret
  end;
  if m_Master.m_LastHiter <> nil then begin  //if someone hit our master
    if (m_Master.m_LastHiter.m_PEnvir = m_PEnvir) and (ispropertarget(m_Master.m_LastHiter)) then // if whoever hit our master is also on same map as us
      m_TargetCret := m_Master.m_LastHiter;
  end;
end;

function TClone.GetShowName: String;
begin
  Result := 'TClone';

  try
    if m_Master <> nil then begin
      Result := m_Master.GetShowName;
    end;
  except
    MainOutMessage('[Exception] TClone.GetShowName');
  end;
end;


{Minotaur King}
constructor TMinotaurKing.Create;//004AA4B4
begin
  inherited;
  nextx:=0;
  nexty:=0;
  boMoving:=FALSE;
  MassAttackMode:=FALSE;
  MassAttackCount:=0;
  NextTarget:=nil;
  m_boApproach:=FALSE;//stops mtk from going towards players
  m_dwSearchTime:=Random(1500) + 1500;
end;

destructor TMinotaurKing.Destroy;
begin
  inherited;
end;

function TMinotaurKing.Operate(ProcessMsg:pTProcessMessage):boolean;
begin
  if (ProcessMsg.wIdent = RM_MAGSTRUCK) and (not MassAttackMode) then begin
    //they used magic now pwn them with redcircle!!!!!!
    MassAttackMode:=True;
    MassAttackCount:=0;
  end;
  Result := inherited Operate(ProcessMsg);
end;

procedure TMinotaurKing.RedCircle(nDir:Integer);
var
  I:Integer;
  magpwr:Integer;
  WAbil:pTAbility;
  BaseObject:TBaseObject;
  Target:TBaseObject;
begin
//target selected
 m_btDirection:=nDir;
 { get first target }
 if NextTarget <> nil then begin
  Target:=NextTarget;
  NextTarget:=nil;
 end else begin
  Target := m_TargetCret;
 end;
 {do spell effect}
 SendRefMsg(RM_LIGHTING,1,m_nCurrX,m_nCurrY,Integer(Target),'');

 {do hit radius around target}
  for i:=0 to Target.m_VisibleActors.Count-1 do begin
    BaseObject:= TBaseObject (pTVisibleBaseObject(Target.m_VisibleActors[i]).BaseObject);
    if (abs(Target.m_nCurrX-BaseObject.m_nCurrX) <= 3) and (abs(Target.m_nCurrY-BaseObject.m_nCurrY) <= 3) then begin
     //if in 3 radious range get hit
      if BaseObject <> nil then begin
        if IsProperTarget (BaseObject) then begin
          if random(3) = 0 then NextTarget:=BaseObject;
          if Random(50) >= BaseObject.m_nAntiMagic then begin
            WAbil:=@m_WAbil;
            magpwr:=(Random(SmallInt(HiWord(WAbil.MC) - LoWord(WAbil.MC)) + 1) + LoWord(WAbil.MC));
            BaseObject.SendDelayMsg (self, RM_MAGSTRUCK, 0, magpwr, 0, 0, '', 600);
          end;
        end;
      end;
     end;
  end;
end;


procedure TMinotaurKing.Run;//004AA604
var
  nAttackDir:Integer;
  distx,disty,distx2,disty2:Integer;
begin

  if (not bo554) and CanMove then begin

    if ((GetTickCount - m_dwSearchEnemyTick) > 1000) and (m_TargetCret = nil) then begin
      m_dwSearchEnemyTick:=GetTickCount();
      SearchTarget();
    end;

    //walk code (only make him to towards a target if it's just at the edge of our view range
    if (m_TargetCret <> nil) then begin
      distx := abs(m_nCurrX - m_TargetCret.m_nCurrX);
      disty := abs(m_nCurrY - m_TargetCret.m_nCurrY);
      if (nextx = 0) and (nexty = 0) then begin
        nextx:=m_TargetCret.m_nCurrX ;
        nexty:=m_TargetCret.m_nCurrY;
      end;
    end;
    if boMoving then begin //if moving is true check if we havent reached our destination
      if ((m_nCurrx = nextx) and (m_nCurry = nexty)) then begin
        boMoving:=False;
        nextx:=0;
        nexty:=0;
      end;
      distx2 := abs(m_nCurrX - nextx);
      disty2 := abs(m_nCurrY - nexty);
      if (distx2 < 2) and (disty2 < 2) and (m_PEnvir.MoveToMovingObject(m_nCurrX,m_nCurrY,Self,nextx,nexty,FALSE) <= 0) then begin //if we reached our destination, should add a code to check if there's nobody else there later
        boMoving:=False;
        nextx:=0;
        nexty:=0;
      end;
    end;
    if ((m_TargetCret = nil) or ((distx > 7) or (disty > 7))) and (nextx <> 0) and (nexty <> 0) then
      boMoving:=True;

    if boMoving then begin
      if (GetCurrentTime - m_dwWalkTick > GetWalkSpeed) then begin //check if we should walk closer or not and do it :p
        m_dwWalkTick:=GetCurrentTime;
        m_nTargetX:=nextx;
        m_nTargetY:=nexty;
        GotoTargetXY();
      end;
    end;

    {attack them at distance}
    if (m_TargetCret <> nil) and
        (_max(distx,disty) > 1) and
        (Integer(GetTickCount - m_dwHitTick) > 1200) and
        (not MassAttackMode) then begin
      nAttackDir:=GetNextDirection(m_nCurrX,m_nCurrY,m_TargetCret.m_nCurrX,m_TargetCret.m_nCurrY);
      m_dwHitTick:=GetCurrentTime;
      RedCircle(nAttackDir);
    end;

    {Actual magic attack if hes hit by magic}
    if (Integer(GetTickCount - m_dwHitTick) > 1200) and (m_TargetCret <> nil) then begin
      if (MassAttackMode) then begin
        if (MassAttackCount <= 5) then begin
          m_dwHitTick:=GetCurrentTime;
          inc(MassAttackCount);
          nAttackDir:=GetNextDirection(m_nCurrX,m_nCurrY,m_TargetCret.m_nCurrX,m_TargetCret.m_nCurrY);
          RedCircle(nAttackDir);
        end else begin
          MassAttackCount := 0;
          MassAttackMode := False;
        end;
      end;
    end;
  end;
  inherited;
end;

 {LEFT & RIGHT GUARDS}

constructor TMinoGuard.Create; //004A9690
begin
  inherited;
  m_dwSearchTime:=Random(1500) + 1500;
  m_dwHitTick:=GetCurrentTime;
end;

destructor TMinoGuard.Destroy;
begin
  inherited;
end;

procedure TMinoGuard.MagicAttack(nDir:Integer);
var
Target:TBaseObject;
magpwr:Integer;
WAbil:pTAbility;
begin
if m_TargetCret <> nil then Target:=m_TargetCret;

SendRefMsg(RM_LIGHTING,1,m_nCurrX,m_nCurrY,Integer(Target),'');

 {Hit first Target}
 if IsProperTarget (Target) then begin
  if Random(50) >= Target.m_nAntiMagic then begin
       WAbil:=@m_WAbil;
       magpwr:=(Random(SmallInt(HiWord(WAbil.MC) - LoWord(WAbil.MC)) + 1) + LoWord(WAbil.MC));
       Target.SendDelayMsg (self, RM_MAGSTRUCK, 0, magpwr, 0, 0, '', 600);
  end;
 end;
end;

procedure TMinoGuard.Run;//004A9720
var
nAttackDir:integer;
begin
  if not bo554 and CanMove then begin

     if (m_TargetCret <> nil) and
       ((abs(m_nCurrX - m_TargetCret.m_nCurrX) >= 2) or
       (abs(m_nCurrY - m_TargetCret.m_nCurrY) >= 2)) and
       (Integer(GetTickCount - m_dwHitTick) > 2200) then begin
      if (MagCanHitTarget(m_nCurrX,m_nCurrY,m_targetCret)) or (m_btRaceImg <> 70) then begin //make sure the 'line' in wich magic will go isnt blocked
        m_dwHitTick:=GetCurrentTime;
        nAttackDir:=GetNextDirection(m_nCurrX,m_nCurrY,m_TargetCret.m_nCurrX,m_TargetCret.m_nCurrY);
        MagicAttack(nAttackDir);
      end;
     end;

    if ((GetTickCount - m_dwSearchEnemyTick) > 8000) or
       (((GetTickCount - m_dwSearchEnemyTick) > 1000) and (m_TargetCret = nil)) then begin
      m_dwSearchEnemyTick:=GetTickCount();
      SearchTarget();
    end;
  end;
  inherited;
end;

constructor TNodeMonster.Create;
begin
  inherited;
  m_boAnimal:=False;
end;

destructor TNodeMonster.Destroy;
begin

  inherited;
end;

procedure TNodeMonster.Run;//004A617C
begin
  if (not m_boDeath) and (not m_boGhost) then begin
    if ((GetTickCount - m_dwSearchEnemyTick) > 18000) then begin
      m_dwSearchEnemyTick:=GetTickCount();
      Search();
    end;
    if (GetCurrentTime - m_dwWalkTick > GetWalkSpeed) then begin
      m_dwWalkTick:=GetCurrentTime;
      SendRefMsg(RM_TURN,m_btDirection,m_nCurrX,m_nCurrY,0,'');
    end;
  end;
  inherited;
end;

procedure TNodeMonster.Search(); //find all the 'allies' (aka other mobs) nearby
var
  xTargetList:TList;
  BaseObject:TBaseObject;
  i:Integer;
begin
  xTargetList := TList.Create;
  GetMapBaseObjects(m_PEnvir,m_nCurrX,m_nCurrY,12,xTargetList);
	if (xTargetList.Count>0) then begin
    SendRefMsg(RM_HIT,m_btDirection,m_nCurrX,m_nCurrY,0,'');
    for i:=xTargetList.Count-1 downto 0 do begin
      BaseObject := TBaseObject(xTargetList.Items[i]);

      if (BaseObject<>nil) then begin
      if BaseObject.m_btRaceServer <> RC_PLAYOBJECT then begin //basicaly if it's not a player then we shield it (even if it's an npc :p)
        CastShield(BaseObject)
      end;
        xTargetList.Delete(i);
		  end;
    end;
	end;
  xTargetList.Free;
end;

procedure TNodeMonster.CastShield(BaseObject: TBaseObject);//give our friend his shield
var
  nSec:integer;
begin
  nSec:=20;//set it to 20 seconds 'shield' since the search is only done every 18seconds this means the shield lasts forever technicaly (provided mob stays in range)
  if m_btRaceImg = 75 then begin  //red one: give dc
    BaseObject.AttPowerUp(m_WAbil.MC,nsec)
  end else begin           //blue one: give ac+amc
    BaseObject.DefenceUp(nSec);
    BaseObject.MagDefenceUp(nSec);
  end;
end;

constructor TOmaKing.Create;
begin
  ldistx:=0;
  ldisty:=0;
  m_dwSearchTime:=Random(1500) + 1500;
  m_dwSpellTick:=GetTickCount();
  m_boAnimal:=False;
  inherited;
end;

destructor TOmaKing.Destroy;
begin
  inherited;
end;

procedure TOmaKing.Run;//004AA604
var
  distx,disty:integer;
  nDir:integer;
begin
  if not m_boFixedHideMode and
     not m_boStoneMode and
     CanMove then begin
//walk codes next (since ok doesnt go near players like other mobs do this is hopefully a correct code)
  if (m_TargetCret <> nil) then begin
    if (GetCurrentTime - m_dwWalkTick > GetWalkSpeed) then begin //check if we should walk closer or not and do it :p
      m_dwWalkTick:=GetCurrentTime;
      distx:=abs(m_nCurrX - m_TargetCret.m_nCurrX);
    

⌨️ 快捷键说明

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