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

📄 envir.pas

📁 翎风世界..传奇服务端..DELPHI源代码 包括DBServer,LogDataServer,LoginGate,LoginSrv,M2Server等..内容齐全.
💻 PAS
📖 第 1 页 / 共 3 页
字号:
unit Envir;

interface

uses
  Windows, SysUtils, Classes,dialogs, Grobal2,mudutil, SDK;
type
  TEnvirnoment = class;

  
  pTOSObject=^TOSObject;
  TOSObject=record
     btType:byte;
     CellObj:TObject;
     dwAddTime:dword;
  end;

  TMapHeader = packed record
    wWidth      :Word;
    wHeight     :Word;
    sTitle      :String[16];
    UpdateDate  :TDateTime;
    Reserved    :array[0..22] of Char;
  end;
  TMapUnitInfo = packed record
    wBkImg        :Word;  //32768 $8000 为禁止移动区域
    wMidImg       :Word;
    wFrImg        :Word;
    btDoorIndex   :Byte;  //$80 (巩娄), 巩狼 侥喊 牢郸胶
    btDoorOffset  :Byte;  //摧腮 巩狼 弊覆狼 惑措 困摹, $80 (凯覆/摧塞(扁夯))
    btAniFrame    :Byte;      //$80(Draw Alpha) +  橇贰烙 荐
    btAniTick     :Byte;
    btArea        :Byte;        //瘤开 沥焊
    btLight       :Byte;       //0..1..4 堡盔 瓤苞
  end;
  pTMapUnitInfo =^TMapUnitInfo;
  TMap = array[0..1000 * 1000 -1] of TMapUnitInfo;
  pTMap = ^TMap;
  TMapCellinfo = record
    chFlag   :Byte;
    ObjList  :TList;
  end;
  pTMapCellinfo =^TMapCellinfo;

  TEnvirnoment = class
    Header             :TMapHeader;

    sMapName           :String; //0x4
    sMapDesc           :String;
    MapCellArray       :array of TMapCellinfo; //0x0C
    nMinMap            :Integer; //0x10
    nServerIndex       :Integer; //0x14
    nRequestLevel      :Integer; //0x18 进入本地图所需等级

    Flag               :TMapFlag;
    bo2C               :Boolean;
    m_DoorList         :TList;
    QuestNPC           :TObject;
    m_QuestList        :TList;
    m_dwWhisperTick    :LongWord;

  private
    m_nMonCount        :Integer;
    m_nHumCount        :Integer;
    
    procedure Initialize(nWidth, nHeight: Integer);
  public
    constructor Create();
    destructor Destroy; override;
    function AddToMap(nX,nY:Integer;btType:Byte;pRemoveObject:TObject):Pointer;
    function CanWalk (nX,nY:Integer;boFlag:Boolean = False):Boolean;
    function CanWalkOfItem (nX,nY:Integer;boFlag,boItem:Boolean):Boolean;
    function CanWalkEx (nX,nY:Integer;boFlag:Boolean):Boolean;
    function CanFly (nsX,nsY,ndX,ndY:integer):Boolean;    
    function MoveToMovingObject(nCX, nCY: integer; Cert: TObject; nX,nY: Integer; boFlag: Boolean): Integer;
    function GetItem(nX, nY: Integer): PTMapItem;
    function DeleteFromMap(nX,nY:Integer;btType:Byte;pRemoveObject:TObject):Integer;
    function IsCheapStuff():Boolean;
    procedure AddDoorToMap;
    function  AddToMapMineEvent(nX,nY:Integer;nType:Integer;Event:TObject):TObject;
    function  LoadMapData(sMapFile:String):Boolean;
    function  CreateQuest(nFlag,nValue:Integer;sMonName,sItem,sQuest:String;boGrouped:Boolean):Boolean;
    function  GetMapCellInfo(nX,nY:Integer;var MapCellInfo:pTMapCellinfo):Boolean;
    function  GetXYObjCount(nX,nY:Integer):Integer;
    function  GetNextPosition(sx, sy, ndir,nFlag:Integer;var snx:Integer;var sny:Integer):Boolean;
    function  IsValidCell(nX,nY:Integer):Boolean;
    procedure VerifyMapTime(nX,nY:Integer;BaseObject:TObject);
    function  CanSafeWalk(nX,nY:Integer):Boolean;
    function  ArroundDoorOpened(nX,nY:Integer):Boolean;
    function  GetMovingObject(nX,nY:Integer;boFlag:Boolean):Pointer;
    function  GetQuestNPC(BaseObject:TObject;sCharName,sItem:String;boFlag:Boolean):TObject;
    function  GetItemEx(nX,nY:Integer;var nCount:Integer):Pointer;
    function  GetDoor(nX,nY:Integer):pTDoorInfo;
    function  IsValidObject(nX,nY:Integer;nRage:Integer;BaseObject:TObject):Boolean;
    function  GetRangeBaseObject(nX,nY:Integer;nRage:Integer;boFlag:Boolean;BaseObjectList:TList):Integer;
    function  GetBaseObjects(nX,nY:Integer;boFlag:Boolean;BaseObjectList:TList):Integer;
    function  GetEvent(nX,nY:Integer):TObject;
    procedure SetMapXYFlag(nX,nY:Integer;boFlag:Boolean);
    function  GetXYHuman(nMapX, nMapY: Integer):Boolean;
    function  GetEnvirInfo():String;
    procedure AddObject(BaseObject:TObject);
    procedure DelObjectCount(BaseObject:TObject);
    property  MonCount:Integer read m_nMonCount;
    property  HumCount:Integer read m_nHumCount;
  end;
  TMapManager = class(TGList)  //004B52B0
  private
  public
    constructor Create();
    destructor Destroy; override;  
    procedure LoadMapDoor();
    function AddMapInfo(sMapName, sMapDesc: String; nServerNumber: Integer;MapFlag:pTMapFlag;QuestNPC: TObject):TEnvirnoment;
    function GetMapInfo(nServerIdx: Integer;sMapName: String): TEnvirnoment;
    function AddMapRoute(sSMapNO:String;nSMapX,nSMapY:Integer;sDMapNO:String;nDMapX,nDMapY:Integer):Boolean;
    function GetMapOfServerIndex(sMapName:String):Integer;
    function FindMap(sMapName:String):TEnvirnoment;
    procedure ReSetMinMap();
    procedure Run();
    procedure ProcessMapDoor();
  end;
implementation

uses ObjBase, ObjNpc, M2Share, Event, ObjMon, HUtil32, Castle;

{ TEnvirList }

//004B7038
function TMapManager.AddMapInfo(sMapName, sMapDesc: String; nServerNumber:Integer;MapFlag:pTMapFlag;QuestNPC: TObject):TEnvirnoment;
var
  Envir:TEnvirnoment;
  i:Integer;
begin
  Result:=nil;
  Envir:=TEnvirnoment.Create;
  Envir.sMapName           :=sMapName;
  Envir.sMapDesc           :=sMapDesc;
  Envir.nServerIndex       :=nServerNumber;

  Envir.Flag               :=MapFlag^;
  Envir.QuestNPC           :=QuestNPC;

  for i:=0 to MiniMapList.Count -1 do begin
    if CompareText(MiniMapList.Strings[i],Envir.sMapName) = 0 then begin
      Envir.nMinMap:=Integer(MiniMapList.Objects[i]);
      break;
    end;
  end;
  if Envir.LoadMapData(g_Config.sMapDir + sMapName + '.map') then begin
    Result:=Envir;
    Self.Add(Envir);
  end else begin
    MainOutMessage('Failure: ' + g_Config.sMapDir + sMapName + '.map' + ' could not be loaded.');
  end;
end;
//004B7280
function TMapManager.AddMapRoute(sSMapNO:String;nSMapX,nSMapY:Integer;sDMapNO:String;nDMapX,nDMapY:Integer):Boolean;
var
  GateObj:pTGateObj;
  SEnvir:TEnvirnoment;
  DEnvir:TEnvirnoment;
begin
  Result:=False;
  SEnvir:=FindMap(sSMapNO);
  DEnvir:=FindMap(sDMapNO);
  if (SEnvir <> nil) and (DEnvir <> nil) then begin
    New(GateObj);
    GateObj.boFlag:=False;
    GateObj.DEnvir:=DEnvir;
    GateObj.nDMapX:=nDMapX;
    GateObj.nDMapY:=nDMapY;
    SEnvir.AddToMap(nSMapX,nSMapY,OS_GATEOBJECT,TObject(GateObj));
    Result:=True;
  end;

end;
//004B63E4
function TEnvirnoment.AddToMap(nX, nY: Integer; btType: Byte;
  pRemoveObject: TObject):Pointer;
var
  MapCellInfo:pTMapCellinfo;
  OSObject:pTOSObject;
  MapItem:PTMapItem;
  i:integer;
  nGoldCount:Integer;
  bo1E:Boolean;
ResourceString
  sExceptionMsg = '[Exception] TEnvirnoment::AddToMap';
begin
  Result:=nil;
  try
    bo1E:=False;
    if GetMapCellInfo(nX,nY,MapCellInfo) and (MapCellInfo.chFlag = 0) then begin
      if MapCellInfo.ObjList = nil then begin
        MapCellInfo.ObjList:=TList.Create;
      end else begin
        if btType = OS_ITEMOBJECT then begin
          if PTMapItem(pRemoveObject).Name = sSTRING_GOLDNAME then begin
            for i:=0 to MapCellInfo.ObjList.Count -1 do begin
              OSObject:=MapCellInfo.ObjList.Items[i];
              if OSObject.btType = OS_ITEMOBJECT then begin
                MapItem:=PTMapItem(pTOSObject(MapCellInfo.ObjList.Items[i]).CellObj);
                if MapItem.Name = sSTRING_GOLDNAME then begin
                  nGoldCount:=MapItem.Count + PTMapItem(pRemoveObject).Count;
                  if nGoldCount <= 2000 then begin
                    MapItem.Count:= nGoldCount;
                    MapItem.Looks:= GetGoldShape(nGoldCount);
                    MapItem.AniCount:=0;
                    MapItem.Reserved:=0;
                    OSObject.dwAddTime:=GetTickCount();
                    Result:=MapItem;
                    bo1E:=True;
                  end;
                end;
              end;
            end;//004B653D
          end;//004B653D
          if not bo1E and (MapCellInfo.ObjList.Count >= 5) then begin
            Result:=nil;
            bo1E:=True;
          end;//004B6558
        end;//004B6558
        if btType = OS_EVENTOBJECT then begin

        end;
      end;//004B655C
      if not bo1E then begin
        New(OSObject);
        OSObject.btType:=btType;
        OSObject.CellObj:=pRemoveObject;
        OSObject.dwAddTime:=GetTickCount();
        MapCellInfo.ObjList.Add(OSObject);
        Result:=Pointer(pRemoveObject);

        if (btType = OS_MOVINGOBJECT) and (not TBaseObject(pRemoveObject).m_boAddToMaped) then begin
          TBaseObject(pRemoveObject).m_boDelFormMaped:=False;
          TBaseObject(pRemoveObject).m_boAddToMaped:=True;
          AddObject(pRemoveObject);
        end;
        
      end;//004B659F

    end;//004B659F
  except
    MainOutMessage(sExceptionMsg);
  end;
end;

procedure TEnvirnoment.AddDoorToMap(); //004B6A74
var
  i:integer;
  Door:pTDoorInfo;
begin
  for i:=0 to m_DoorList.Count -1 do begin
    Door:=m_DoorList.Items[i];
    AddToMap(Door.nX,Door.nY,OS_DOOR,TObject(Door));
  end;
end;
function TEnvirnoment.GetMapCellInfo(nX,nY:Integer;var MapCellInfo:pTMapCellinfo):Boolean;//004B57D8
begin
  if (nX >= 0) and (nX < Header.wWidth) and (nY >= 0) and (nY < Header.wHeight) then begin
    MapCellInfo:=@MapCellArray[nX * Header.wHeight + nY];
    Result:=True;
  end else begin//004B5829
    Result:=False;
  end;
end;
function TEnvirnoment.MoveToMovingObject (nCX, nCY:integer;Cert:TObject;nX,nY:Integer;boFlag:Boolean):Integer;//004B612C
var
  MapCellInfo:pTMapCellinfo;
  BaseObject:TBaseObject;
  OSObject:pTOSObject;
  i:Integer;
  bo1A:Boolean;
ResourceString
  sExceptionMsg = '[Exception] TEnvirnoment::MoveToMovingObject';
label
  Loop,Over;
begin
  Result:=0;
  try
    bo1A:=True;
    if not boFlag and GetMapCellInfo(nX,nY,MapCellInfo) then begin
      if MapCellInfo.chFlag = 0 then begin
        if MapCellInfo.ObjList <> nil then begin
          for i:=0 to MapCellInfo.ObjList.Count -1 do begin//004B61AD
            if pTOSObject(MapCellInfo.ObjList.Items[i]).btType = OS_MOVINGOBJECT then begin
              BaseObject:=TBaseObject(pTOSObject(MapCellInfo.ObjList.Items[i]).CellObj);
              if BaseObject <> nil then begin//004B61DB
                if not BaseObject.m_boGhost
                and BaseObject.bo2B9
                and not BaseObject.m_boDeath
                and not BaseObject.m_boFixedHideMode
                and not BaseObject.m_boObMode then begin
                  bo1A:=False;
                  Break;
                end;
              end;//004B6223
            end;//004B6223
          end;//004B622D
        end;//004B6238
      end else begin//004B622D   if MapCellInfo.chFlag = 0 then begin
        Result:= -1;
        bo1A:=False;
      end;//004B6238
    end;//004B6238
    if bo1A then begin  //004B6238
      if GetMapCellInfo(nX,nY,MapCellInfo) and (MapCellInfo.chFlag <> 0) then begin
        Result:= -1;
      end else begin//004B6265
        if GetMapCellInfo(nCX,nCY,MapCellInfo) and (MapCellInfo.ObjList <> nil) then begin
          i:=0;
          while (True) do begin
            if MapCellInfo.ObjList.Count <= i then break;
            OSObject:=MapCellInfo.ObjList.Items[i];
            if OSObject.btType = OS_MOVINGOBJECT then begin
              if TBaseObject(OSObject.CellObj) = TBaseObject(Cert) then begin
                MapCellInfo.ObjList.Delete(i);
                Dispose(OSObject);
                if MapCellInfo.ObjList.Count > 0 then Continue;
                MapCellInfo.ObjList.Free;
                MapCellInfo.ObjList:=nil;
                break;
              end;
             end;
            Inc(i);
          end;
        end;//4B6311
        if GetMapCellInfo(nX,nY,MapCellInfo) then begin
          if (MapCellInfo.ObjList = nil) then begin
            MapCellInfo.ObjList:=TList.Create;
          end;
          New(OSObject);
          OSObject.btType:=OS_MOVINGOBJECT;
          OSObject.CellObj:=Cert;
          OSObject.dwAddTime:=GetTickCount;
          MapCellInfo.ObjList.Add(OSObject);
          Result:=1;
        end;//004B6383
      end;//004B6383
    end;//004B6383
  except
    on e: Exception do begin
      MainOutMessage(sExceptionMsg);
      MainOutMessage(E.Message);
    end;
  end;
//  pMapCellInfo = GetMapCellInfo(nX, nY);
end;
//======================================================================
//检查地图指定座标是否可以移动
//boFlag  如果为TRUE 则忽略座标上是否有角色
//返回值 True 为可以移动,False 为不可以移动
//======================================================================
function TEnvirnoment.CanWalk(nX, nY: Integer; boFlag: Boolean = False): Boolean;//004B5ED0
var
  MapCellInfo:pTMapCellinfo;
  OSObject:pTOSObject;
  BaseObject       :TBaseObject;
  i:Integer;
begin
  Result:=False;
  if GetMapCellInfo(nX,nY,MapCellInfo) and (MapCellInfo.chFlag = 0) then begin
    Result:=True;
    if not boFlag and (MapCellInfo.ObjList <> nil) then begin
      for i:=0 to MapCellInfo.ObjList.Count - 1 do begin
        OSObject:=MapCellInfo.ObjList.Items[i];
        if OSObject.btType = OS_MOVINGOBJECT then begin
          BaseObject:=TBaseObject(OSObject.CellObj);
          if BaseObject <> nil then begin
            if not BaseObject.m_boGhost
            and BaseObject.bo2B9
            and not BaseObject.m_boDeath
            and not BaseObject.m_boFixedHideMode
            and not BaseObject.m_boObMode then begin
              Result:=False;
              Break;
            end;
          end;//004B5FB5
        end;//004B5FB5
      end;
    end;
  end;//004B5FBD
end;

//======================================================================
//检查地图指定座标是否可以移动
//boFlag  如果为TRUE 则忽略座标上是否有角色
//返回值 True 为可以移动,False 为不可以移动
//======================================================================
function TEnvirnoment.CanWalkOfItem(nX, nY: Integer; boFlag,boItem: Boolean): Boolean;//004B5ED0
var
  MapCellInfo:pTMapCellinfo;
  OSObject:pTOSObject;
  BaseObject       :TBaseObject;
  i:Integer;
begin
  Result:=True;
  if GetMapCellInfo(nX,nY,MapCellInfo) and (MapCellInfo.chFlag = 0) then begin
//    Result:=True;
    if  (MapCellInfo.ObjList <> nil) then begin
      for i:=0 to MapCellInfo.ObjList.Count - 1 do begin
        OSObject:=MapCellInfo.ObjList.Items[i];
        if not boFlag and (OSObject.btType = OS_MOVINGOBJECT) then begin
          BaseObject:=TBaseObject(OSObject.CellObj);
          if BaseObject <> nil then begin
            if not BaseObject.m_boGhost
            and BaseObject.bo2B9
            and not BaseObject.m_boDeath
            and not BaseObject.m_boFixedHideMode
            and not BaseObject.m_boObMode then begin
              Result:=False;
              Break;
            end;
          end;//004B5FB5
        end;//004B5FB5
        if not boItem and (OSObject.btType = OS_ITEMOBJECT) then begin
          Result:=False;
          break;
        end;
      end;
    end;
  end;//004B5FBD
end;

function TEnvirnoment.CanWalkEx(nX, nY: Integer; boFlag: Boolean): Boolean;//004B5ED0
var
  MapCellInfo:pTMapCellinfo;
  OSObject:pTOSObject;
  BaseObject       :TBaseObject;
  i:Integer;
  Castle:TUserCastle;
begin
  Result:=False;
  if GetMapCellInfo(nX,nY,MapCellInfo) and (MapCellInfo.chFlag = 0) then begin
    Result:=True;
    if not boFlag and (MapCellInfo.ObjList <> nil) then begin
      for i:=0 to MapCellInfo.ObjList.Count - 1 do begin
        OSObject:=MapCellInfo.ObjList.Items[i];
        if OSObject.btType = OS_MOVINGOBJECT then begin
          BaseObject:=TBaseObject(OSObject.CellObj);
          if BaseObject <> nil then begin
            {//01/25 多城堡 控制
            if g_Config.boWarDisHumRun and UserCastle.m_boUnderWar and
              UserCastle.InCastleWarArea(BaseObject.m_PEnvir,BaseObject.m_nCurrX,BaseObject.m_nCurrY) then begin
            }
            Castle:=g_CastleManager.InCastleWarArea(BaseObject);
            if g_Config.boWarDisHumRun and (Castle <> nil) and (Castle.m_boUnderWar) then begin
            end else begin
              if BaseObject.m_btRaceServer =RC_PLAYOBJECT then begin
                if g_Config.boRunHuman or Flag.boRUNHUMAN then Continue;
              end else begin
                if BaseObject.m_btRaceServer = RC_NPC then begin
                  if g_Config.boRunNpc then Continue;
                end else begin
                  if BaseObject.m_btRaceServer in [RC_GUARD,RC_ARCHERGUARD] then begin
                    if g_Config.boRunGuard then Continue;
                  end else begin
                    if g_Config.boRunMon or Flag.boRUNMON then Continue;
                  end;

⌨️ 快捷键说明

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