📄 envir.pas
字号:
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;
//======================================================================
//检查地图指定座标是否可以移动
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -