📄 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;
//======================================================================
//检查地图指定座标是否可以移动
//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 + -