📄 envir1.pas
字号:
unit Envir;
interface
uses
Windows, SysUtils, Classes, Grobal2;
type
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;
bt1: Byte;
bt2: Byte;
bt3: Byte;
ObjList: TList;
boListDisPose: Boolean;
end;
pTMapCellinfo = ^TMapCellinfo;
PTEnvirnoment = ^TEnvirnoment;
TEnvirnoment = class
sMapName: string; //0x4
sMapDesc: string;
sMainMapName: string; //0x4
sSubMapName: string; //0x4
m_boMainMap: Boolean; //0x25
MapCellArray: array of TMapCellinfo; //0x0C
nMinMap: Integer; //0x10
nServerIndex: Integer; //0x14
nRequestLevel: Integer; //0x18 进入本地图所需等级
m_nWidth: Integer; //0x1C
m_nHeight: Integer; //0x20
m_boDARK: Boolean; //0x24
m_boDAY: Boolean; //0x25
m_boDarkness: Boolean;
m_boDayLight: Boolean;
m_DoorList: TList; //0x28
bo2C: Boolean;
m_boSAFE: Boolean; //0x2D
m_boFightZone: Boolean; //0x2E
m_boFight3Zone: Boolean; //0x2F //行会战争地图
m_boQUIZ: Boolean; //0x30
m_boNORECONNECT: Boolean; //0x31
m_boNEEDHOLE: Boolean; //0x32
m_boNORECALL: Boolean; //0x33
m_boNOGUILDRECALL: Boolean;
m_boNODEARRECALL: Boolean;
m_boNOMASTERRECALL: Boolean;
m_boNORANDOMMOVE: Boolean; //0x34
m_boNODRUG: Boolean; //0x35
m_boMINE: Boolean; //0x36
m_boNOPOSITIONMOVE: Boolean; //0x37
sNoReconnectMap: string; //0x38
QuestNPC: TObject; //0x3C
nNEEDSETONFlag: Integer; //0x40
nNeedONOFF: Integer; //0x44
m_QuestList: TList; //0x48
m_boRUNHUMAN: Boolean; //可以穿人
m_boRUNMON: Boolean; //可以穿怪
m_boINCHP: Boolean; //自动加HP值
m_boIncGameGold: Boolean; //自动减游戏币
m_boINCGAMEPOINT: Boolean; //自动加点
m_boDECHP: Boolean; //自动减HP值
m_boDecGameGold: Boolean; //自动减游戏币
m_boDECGAMEPOINT: Boolean; //自动减点
m_boMUSIC: Boolean; //音乐
m_boEXPRATE: Boolean; //杀怪经验倍数
m_boPKWINLEVEL: Boolean; //PK得等级
m_boPKWINEXP: Boolean; //PK得经验
m_boPKLOSTLEVEL: Boolean; //PK丢等级
m_boPKLOSTEXP: Boolean; //PK丢经验
m_nPKWINLEVEL: Integer; //PK得等级数
m_nPKLOSTLEVEL: Integer; //PK丢等级
m_nPKWINEXP: Integer; //PK得经验数
m_nPKLOSTEXP: Integer; //PK丢经验
m_nDECHPTIME: Integer; //减HP间隔时间
m_nDECHPPOINT: Integer; //一次减点数
m_nINCHPTIME: Integer; //加HP间隔时间
m_nINCHPPOINT: Integer; //一次加点数
m_nDECGAMEGOLDTIME: Integer; //减游戏币间隔时间
m_nDecGameGold: Integer; //一次减数量
m_nDECGAMEPOINTTIME: Integer; //减游戏点间隔时间
m_nDECGAMEPOINT: Integer; //一次减数量
m_nINCGAMEGOLDTIME: Integer; //加游戏币间隔时间
m_nIncGameGold: Integer; //一次加数量
m_nINCGAMEPOINTTIME: Integer; //加游戏币间隔时间
m_nINCGAMEPOINT: Integer; //一次加数量
m_nMUSICID: Integer; //音乐ID
m_nEXPRATE: Integer; //经验倍率
m_nMonCount: Integer;
m_nHumCount: Integer;
m_boUnAllowStdItems: Boolean; //是否不允许使用物品
m_UnAllowStdItemsList: TGStringList; //不允许使用物品列表
m_boAutoMakeMonster: Boolean;
private
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): 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; s24, s28, s2C: 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 sub_4B5FC8(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, sStr: 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;
function AllowStdItems(sItemName: string): Boolean; overload;
function AllowStdItems(nItemIdx: Integer): Boolean; overload;
procedure AddObject(nType: Integer);
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, sMainMapName, 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;
function GetMainMap(Envir: TEnvirnoment): string;
procedure ReSetMinMap();
procedure Run();
procedure ProcessMapDoor();
procedure MakeSafePkZone();
end;
implementation
uses ObjBase, ObjNpc, M2Share, Event, ObjMon, HUtil32, Castle;
{ TEnvirList }
//004B7038
procedure TMapManager.MakeSafePkZone();
var
nX, nY: Integer;
SafeEvent: TSafeEvent;
nMinX, nMaxX, nMinY, nMaxY: Integer;
nRange, nType, nTime, nPoint: Integer;
I: Integer;
StartPoint: pTStartPoint;
Envir: TEnvirnoment;
begin
g_StartPointList.Lock;
for I := 0 to g_StartPointList.Count - 1 do begin
StartPoint := pTStartPoint(g_StartPointList.Objects[I]);
if (StartPoint <> nil) and (StartPoint.m_nType > 0) then begin
Envir := FindMap(StartPoint.m_sMapName);
if Envir <> nil then begin
nMinX := StartPoint.m_nCurrX - StartPoint.m_nRange;
nMaxX := StartPoint.m_nCurrX + StartPoint.m_nRange;
nMinY := StartPoint.m_nCurrY - StartPoint.m_nRange;
nMaxY := StartPoint.m_nCurrY + StartPoint.m_nRange;
for nX := nMinX to nMaxX do begin
for nY := nMinY to nMaxY do begin
if ((nX < nMaxX) and (nY = nMinY)) or
((nY < nMaxY) and (nX = nMinX)) or
(nX = nMaxX) or (nY = nMaxY) then begin
SafeEvent := TSafeEvent.Create(Envir, nX, nY, StartPoint.m_nType);
g_EventManager.AddEvent(SafeEvent);
end;
end;
end;
end;
end;
end;
end;
function TMapManager.AddMapInfo(sMapName, sMainMapName, sMapDesc: string; nServerNumber: Integer; MapFlag: pTMapFlag; QuestNPC: TObject): TEnvirnoment;
var
Envir: TEnvirnoment;
I: Integer;
nStd: Integer;
TempList: TStringList;
begin
Result := nil;
Envir := TEnvirnoment.Create;
Envir.sMapName := sMapName;
Envir.sMainMapName := sMainMapName;
Envir.sSubMapName := sMapName;
Envir.sMapDesc := sMapDesc;
if sMainMapName <> '' then Envir.m_boMainMap := True;
Envir.nServerIndex := nServerNumber;
Envir.m_boSAFE := MapFlag.boSAFE;
Envir.m_boFightZone := MapFlag.boFIGHT;
Envir.m_boFight3Zone := MapFlag.boFIGHT3;
Envir.m_boDARK := MapFlag.boDARK;
Envir.m_boDAY := MapFlag.boDAY;
Envir.m_boQUIZ := MapFlag.boQUIZ;
Envir.m_boNORECONNECT := MapFlag.boNORECONNECT;
Envir.m_boNEEDHOLE := MapFlag.boNEEDHOLE;
Envir.m_boNORECALL := MapFlag.boNORECALL;
Envir.m_boNOGUILDRECALL := MapFlag.boNOGUILDRECALL;
Envir.m_boNODEARRECALL := MapFlag.boNODEARRECALL;
Envir.m_boNOMASTERRECALL := MapFlag.boNOMASTERRECALL;
Envir.m_boNORANDOMMOVE := MapFlag.boNORANDOMMOVE;
Envir.m_boNODRUG := MapFlag.boNODRUG;
Envir.m_boMINE := MapFlag.boMINE;
Envir.m_boNOPOSITIONMOVE := MapFlag.boNOPOSITIONMOVE;
Envir.m_boRUNHUMAN := MapFlag.boRUNHUMAN; //可以穿人
Envir.m_boRUNMON := MapFlag.boRUNMON; //可以穿怪
Envir.m_boDECHP := MapFlag.boDECHP; //自动减HP值
Envir.m_boINCHP := MapFlag.boINCHP; //自动加HP值
Envir.m_boDecGameGold := MapFlag.boDECGAMEGOLD; //自动减游戏币
Envir.m_boDECGAMEPOINT := MapFlag.boDECGAMEPOINT; //自动减游戏币
Envir.m_boIncGameGold := MapFlag.boINCGAMEGOLD; //自动加游戏币
Envir.m_boINCGAMEPOINT := MapFlag.boINCGAMEPOINT; //自动加游戏点
Envir.m_boMUSIC := MapFlag.boMUSIC; //音乐
Envir.m_boEXPRATE := MapFlag.boEXPRATE; //杀怪经验倍数
Envir.m_boPKWINLEVEL := MapFlag.boPKWINLEVEL; //PK得等级
Envir.m_boPKWINEXP := MapFlag.boPKWINEXP; //PK得经验
Envir.m_boPKLOSTLEVEL := MapFlag.boPKLOSTLEVEL;
Envir.m_boPKLOSTEXP := MapFlag.boPKLOSTEXP;
Envir.m_nPKWINLEVEL := MapFlag.nPKWINLEVEL; //PK得等级数
Envir.m_nPKWINEXP := MapFlag.nPKWINEXP; //PK得经验数
Envir.m_nPKLOSTLEVEL := MapFlag.nPKLOSTLEVEL;
Envir.m_nPKLOSTEXP := MapFlag.nPKLOSTEXP;
Envir.m_nPKWINEXP := MapFlag.nPKWINEXP; //PK得经验数
Envir.m_nDECHPTIME := MapFlag.nDECHPTIME; //减HP间隔时间
Envir.m_nDECHPPOINT := MapFlag.nDECHPPOINT; //一次减点数
Envir.m_nINCHPTIME := MapFlag.nINCHPTIME; //加HP间隔时间
Envir.m_nINCHPPOINT := MapFlag.nINCHPPOINT; //一次加点数
Envir.m_nDECGAMEGOLDTIME := MapFlag.nDECGAMEGOLDTIME; //减游戏币间隔时间
Envir.m_nDecGameGold := MapFlag.nDECGAMEGOLD; //一次减数量
Envir.m_nINCGAMEGOLDTIME := MapFlag.nINCGAMEGOLDTIME; //减游戏币间隔时间
Envir.m_nIncGameGold := MapFlag.nINCGAMEGOLD; //一次减数量
Envir.m_nINCGAMEPOINTTIME := MapFlag.nINCGAMEPOINTTIME; //减游戏币间隔时间
Envir.m_nINCGAMEPOINT := MapFlag.nINCGAMEPOINT; //一次减数量
Envir.m_nMUSICID := MapFlag.nMUSICID; //音乐ID
Envir.m_nEXPRATE := MapFlag.nEXPRATE; //经验倍率
Envir.sNoReconnectMap := MapFlag.sReConnectMap;
Envir.QuestNPC := QuestNPC;
Envir.nNEEDSETONFlag := MapFlag.nNEEDSETONFlag;
Envir.nNeedONOFF := MapFlag.nNeedONOFF;
Envir.m_boAutoMakeMonster := MapFlag.boAutoMakeMonster;
if (MapFlag.boUnAllowStdItems) and (MapFlag.sUnAllowStdItemsText <> '') then begin
Envir.m_boUnAllowStdItems := True;
Envir.m_UnAllowStdItemsList := TGStringList.Create;
TempList := TStringList.Create;
ExtractStrings(['|', '\', '/'], [], PChar(Trim(MapFlag.sUnAllowStdItemsText)), TempList);
for I := 0 to TempList.Count - 1 do begin
nStd := UserEngine.GetStdItemIdx(Trim(TempList.Strings[I]));
if nStd >= 0 then
Envir.m_UnAllowStdItemsList.AddObject(Trim(TempList.Strings[I]), TObject(nStd));
end;
TempList.Free;
end;
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 sMainMapName <> '' then begin
if Envir.LoadMapData(g_Config.sMapDir + sMainMapName + '.map') then begin
Result := Envir;
Self.Add(Envir);
end else begin
MainOutMessage('地图文件 ' + g_Config.sMapDir + sMainMapName + '.map' + ' 未找到!!!');
end;
end else begin
if Envir.LoadMapData(g_Config.sMapDir + sMapName + '.map') then begin
Result := Envir;
Self.Add(Envir);
end else begin
MainOutMessage('地图文件 ' + g_Config.sMapDir + sMapName + '.map' + ' 未找到!!!');
end;
end;
end;
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;
function TEnvirnoment.AddToMap(nX, nY: Integer; btType: Byte;
pRemoveObject: TObject): Pointer;
var
MapCellInfo: pTMapCellinfo;
OSObject: pTOSObject;
MapItem: PTMapItem;
I: Integer;
nGoldCount: Integer;
bo1E: Boolean;
btRaceServer: Byte;
nCheckCode: Integer;
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) or (MapCellInfo.boListDisPose) then begin
MapCellInfo.ObjList := TList.Create;
MapCellInfo.boListDisPose := False;
end else begin
if btType = OS_ITEMOBJECT then begin
if PTMapItem(pRemoveObject).Name = sSTRING_GOLDNAME then begin
if (MapCellInfo.ObjList <> nil) and (MapCellInfo.ObjList.Count > 0) and (not MapCellInfo.boListDisPose) then begin
for I := 0 to MapCellInfo.ObjList.Count - 1 do begin
OSObject := pTOSObject(MapCellInfo.ObjList.Items[I]);
if (OSObject <> nil) and (not OSObject.boObjectDisPose) then begin
if OSObject.btType = OS_ITEMOBJECT then begin
MapItem := PTMapItem(pTOSObject(MapCellInfo.ObjList.Items[I]).CellObj);
if MapItem <> nil then begin
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;
end;
end;
end;
end;
if not bo1E and (MapCellInfo.ObjList <> nil) and (MapCellInfo.ObjList.Count >= 5) then begin
Result := nil;
bo1E := True;
end;
end;
if btType = OS_EVENTOBJECT then begin
end;
end;
if not bo1E then begin
OSObject := nil;
nCheckCode := 0;
New(OSObject);
nCheckCode := 1;
OSObject.btType := btType;
OSObject.CellObj := pRemoveObject;
OSObject.dwAddTime := GetTickCount();
OSObject.boObjectDisPose := False;
MapCellInfo.ObjList.Add(OSObject);
nCheckCode := 2;
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;
btRaceServer := TBaseObject(pRemoveObject).m_btRaceServer;
if btRaceServer = RC_PLAYOBJECT then Inc(m_nHumCount);
if btRaceServer >= RC_ANIMAL then Inc(m_nMonCount);
end;
end;
end;
except
if (nCheckCode = 1) and (OSObject <> nil) then begin
DisPose(OSObject);
end;
//MainOutMessage(sExceptionMsg);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -