www.pudn.com > M2Server.rar > DataHandler.pas
////////////////////////////////////////////////////////////////////////////////
// //
// 工程: M2Server //
// 版本: 1.0 //
// 公司: 乐都在线 //
// 网址: http://www.hh8.net //
// 日期: 2005-05-28 //
// //
////////////////////////////////////////////////////////////////////////////////
unit DataHandler;
interface
uses
Windows, Classes, SysUtils, StrUtils, Math, INIFiles, ClassDeclaration, Forms;
////////////////////////////////////////////////////////////////////////////////
type
TItem = class
public
szName: string[20];
wIndex: LongWord;
wStdMode: Word;
wShape: Word;
wWeight: Word;
dwLooks: LongWord;
wDuraMax: LongWord;
dwRSource: LongWord;
dwPrice: LongWord;
m_btType: Byte;
public
function GetUpgrade(nCount, nRandom: Integer): Integer;
procedure GetStandardItem(lpClientItemRcd: PCLIENTITEM_RCD); virtual;
abstract;
procedure GetUpgradeStdItem(lpClientItemRcd: PCLIENTITEM_RCD; lpUserItemRcd:
PUSERITEM_RCD); virtual; abstract;
end;
tStdItem = class(TItem)
public
procedure GetStandardItem(lpClientItemRcd: PCLIENTITEM_RCD); override;
procedure GetUpgradeStdItem(lpClientItemRcd: PCLIENTITEM_RCD; lpUserItemRcd:
PUSERITEM_RCD); override;
end;
TStdItemSpecial = class(TItem)
public
btType: Byte;
wAniCount: Word;
wSource: Word;
wAC: Byte;
wAC2: Byte;
wMAC: Byte;
wMAC2: Byte;
wDC: Byte;
wDC2: Byte;
wMC: Byte;
wMC2: Byte;
wSC: Byte;
wSC2: Byte;
m_btWater: Byte;
m_btWater2: Byte;
m_btFire: Byte;
m_btFire2: Byte;
m_btWind: Byte;
m_btWind2: Byte;
m_btLight: Byte;
m_btLight2: Byte;
m_btEarth: Byte;
m_btEarth2: Byte;
wNeed: Word;
wNeedLevel: Word;
dwStock: LongWord;
dwFeature: LongWord;
wReserved: LongWord;
public
procedure ApplyItemParameters(m_pAddAbility: POBJECTADDABILITY_RCD);
procedure UpgradeRandomItem(btValue: PChar; var nDura, nDuraMax: Word);
procedure GetStandardItem(lpClientItemRcd: PTCLIENTITEM);
procedure GetUpgradeStdItem(lpClientItemRcd: PCLIENTITEM_RCD; lpUserItemRcd:
PUSERITEM_RCD); override;
end;
////////////////////////////////////////////////////////////////////////////////
TMagicInfo = class
public
Def: TSTANDARDMAGIC;
public
function GetPower13(nPwr: Integer; nLevel: Integer): Integer;
function CheckMagicLevelup(pCharObject: TObject; lptMagicRcd:
PHUMANMAGIC_RCD): Boolean;
function MPow: Integer;
function GetSpellPoint(nLevel: Integer): Integer;
function GetPower(nPwr, nLevel: Integer): Integer;
end;
////////////////////////////////////////////////////////////////////////////////
type
TMirMap = class
public
m_stMapFH: TMAPFILEHEADER_RCD;
m_pMapCellInfo: array of TMAPCELLINFO_RCD;
m_szMapName: string;
m_szMapTextName: string;
m_btSeries: Byte;
m_btSeriesVal: Byte;
m_HumCount: Integer;
constructor Create;
destructor Destroy;
function LoadMapData(var pszName: string): Boolean;
procedure FreeMapData;
function CanMove(nX, nY: Integer; fFlag: Boolean = False): Boolean;
function CanSafeWalk(nX, nY: Integer): Boolean;
function MoveToMovingObject(nX, nY, nTargetX, nTargetY: Integer;
pCharObject: TObject): Boolean;
function RemoveObject(nX, nY: Integer; btType: Byte; pRemoveObject:
Pointer): Boolean;
function AddNewObject(nX, nY: Integer; btType: Byte; pAddObject: Pointer):
Boolean;
function GetEvent(nX, nY: Integer): TObject;
function GetItem(nX, nY: Integer): PMAPITEM_RCD;
function GetObject(nX, nY: Integer): TObject;
procedure GetMapObject(nX, nY, nArea: Integer; var pList: TThreadList);
procedure GetAllObject(nX, nY: Integer; var pList: TThreadList);
function GetDupCount(nX, nY: Integer): Integer;
function GetDropPosition(nOrgX, nOrgY, nRange: Integer; var nX, nY:
Integer): Boolean;
function CheckDoorEvent(nX, nY: Integer; var nEvent: Integer): Integer;
function CheckEvent(nX, nY: Integer): Integer;
function IsValidObject(nX, nY, nCheckRange: Integer; pCharObject: TObject):
Boolean;
function GetMapCellInfo(nX, nY: Integer): PMAPCELLINFO_RCD;
end;
////////////////////////////////////////////////////////////////////////////////
// function and procedure declaration
type
MAPINFO_RCD_ARRAY = array of TMAPINFO_RCD;
procedure LoadMap(pMapInfo: PMAPINFO_RCD);
function GetMap(pszMapName: string): TMirMap;
procedure InitMonsterGenInfo;
procedure InitMagicInfo;
procedure InitMonRaceInfo;
function GatMonRaceByName(Name: string): Integer;
function GetPriceByName(Name: string): Integer;
procedure InitStdItemSpecial;
//procedure InitStdItemEtcInfo;
procedure InitMerchantInfo;
procedure InitMoveMapEventInfo;
function InitMapInfo(nServerIndex: Integer): MAPINFO_RCD_ARRAY;
function GetMagicInfo(nMagicID: Integer): TMagicInfo;
function GetMonGenInfo(pszMonName: string): PMONSTERGENINFO_RCD;
function GetMonRaceInfo(pszMonName: string): PMONRACEINFO_RCD;
implementation
uses
ObjectEvent, ObjectEngine, PredefinedData, DataManage, GlobalDefinition,
MainForm, FunctionDeclaration, MyDebug;
//**************************************************************************************
// Procedure And Functions Declares
//**************************************************************************************
{通过物品名称来获取价格}
function GetPriceByName(Name: string): Integer;
Var
i: integer;
begin
Result := 0;
for i := Low(g_pStdItemSpecial) to High(g_pStdItemSpecial) - 1 do
begin
if g_pStdItemSpecial[i].szName = Name then
begin
Result := g_pStdItemSpecial[i].dwPrice;
Break;
end;
end;
end;
{登陆地图}
procedure LoadMap(pMapInfo: PMAPINFO_RCD);
var
szFullName: string;
pMirMap: TMirMap;
begin
pMirMap := TMirMap.Create;
pMirMap.m_btSeries := pMapInfo^.btMapSeries;
pMirMap.m_btSeriesVal := pMapInfo^.btMapSeriesValue;
pMirMap.m_szMapName := pMapInfo^.szMapFileName;
pMirMap.m_szMapTextName := pMapInfo^.szMapName;
szFullName := pMapInfo^.szMapFileName + '.map';
pMirMap.LoadMapData(szFullName);
end;
{通过地图名获取地图}
function GetMap(pszMapName: string): TMirMap;
var
I: Integer;
pMirMap: TMirMap;
begin
with g_xMirMapList.LockList do
begin
for I := 0 to COunt - 1 do // Iterate
begin
pMirMap := TMirMap(items[I]);
if (pMirMap.m_szMapName = pszMapName) then
begin
Result := pMirMap;
g_xMirMapList.UnlockList;
Exit;
end;
end; // for
end; // with
g_xMirMapList.UnlockList;
Result := nil;
end;
{初始化地图信息}
procedure InitMonsterGenInfo;
var
I, j, K: Integer;
MonsterGenStrings, temp: Tstrings;
MonsterGenStr: string;
begin
MonsterGenStrings := TStringList.Create;
K := 0;
try
MonsterGenStrings.LoadFromFile('.\Envir\MonGen.txt');
SetLength(g_pMonGenInfo, MonsterGenStrings.COunt);
///设置g_pmeovmapeventinfo数组的长度,一开始设置得较长;
for I := 0 to MonsterGenStrings.COunt - 1 do
begin
MonsterGenStr := Trim(MonsterGenStrings[I]);
if Length(MonsterGenStr) <> 0 then ///
if MonsterGenStr[1] <> ';' then
begin
temp := SplitStringByChar(MonsterGenStr, [#1..' ']);
//以指定的字符分割字符串
for j := 0 to temp.COunt - 1 do
begin
case j of
0: g_pMonGenInfo[K].szMapName := temp[j];
1: g_pMonGenInfo[K].nX := StrToInt(temp[j]);
2: g_pMonGenInfo[K].nY := StrToInt(temp[j]);
3: g_pMonGenInfo[K].szMonName := temp[j];
4: g_pMonGenInfo[K].Area := StrToInt(temp[j]);
5: g_pMonGenInfo[K].nCount := StrToInt(temp[j]);
6: g_pMonGenInfo[K].GenTime := StrToInt(temp[j]);
7: g_pMonGenInfo[K].nSmallZenRate := StrToInt(temp[j]);
end;
end;
g_pMonGenInfo[K].nMonIndex :=
GatMonRaceByName(g_pMonGenInfo[K].szMonName);
if g_pMonGenInfo[K].nMonIndex = -1 then
Continue;
g_pMonGenInfo[K].xMonsterObjList := TThreadList.Create;
K := K + 1;
temp.Free;
end;
end;
SetLength(g_pMonGenInfo, K); //重新设置长度,缩短数组的大小
g_nNumOfMonGenInfo := K;
finally
MonsterGenStrings.Free;
end;
end;
{初始化魔法信息}
procedure InitMagicInfo;
var
I: Integer;
begin
with DataManager.Query1 do
begin
Close;
sql.Clear;
sql.Add('SELECT MagID, MagName, EffectType, Effect, Spell, Power, MaxPower, DefSpell, DefPower' +
',DefMaxPower, Job, NeedL1, L1Train, NeedL2, L2Train, NeedL3, L3Train, Delay, Descr FROM "Magic.DB" Magic');
open;
first;
SetLength(g_pMagicInfo, RecordCount);
g_nNumOfMagicInfo := RecordCount;
for I := 0 to RecordCount - 1 do
begin
g_pMagicInfo[I] := TMagicInfo.Create;
g_pMagicInfo[I].Def.MagicID := FieldByName('MagID').AsInteger;
g_pMagicInfo[I].Def.MagicName := FieldByName('MagName').AsString;
g_pMagicInfo[I].Def.EffectType := FieldByName('EffectType').AsInteger;
g_pMagicInfo[I].Def.Effect := FieldByName('Effect').AsInteger;
g_pMagicInfo[I].Def.spell := FieldByName('Spell').AsInteger;
g_pMagicInfo[I].Def.mpower := FieldByName('Power').AsInteger;
g_pMagicInfo[I].Def.MaxPower := FieldByName('MaxPower').AsInteger;
g_pMagicInfo[I].Def.defspell := FieldByName('DefSpell').AsInteger;
g_pMagicInfo[I].Def.MinPower := FieldByName('DefPower').AsInteger;
g_pMagicInfo[I].Def.defmaxpower := FieldByName('DefMaxPower').AsInteger;
g_pMagicInfo[I].Def.job := FieldByName('Job').AsInteger;
g_pMagicInfo[I].Def.Need[0] := FieldByName('NeedL1').AsInteger;
g_pMagicInfo[I].Def.Need[1] := FieldByName('NeedL2').AsInteger;
g_pMagicInfo[I].Def.Need[2] := FieldByName('NeedL3').AsInteger;
g_pMagicInfo[I].Def.MaxTrain[0] := FieldByName('L1Train').AsInteger;
g_pMagicInfo[I].Def.MaxTrain[1] := FieldByName('L2Train').AsInteger;
g_pMagicInfo[I].Def.MaxTrain[2] := FieldByName('L3Train').AsInteger;
g_pMagicInfo[I].Def.Delaytime := FieldByName('Delay').AsInteger;
g_pMagicInfo[I].Def.desc := FieldByName('Descr').AsString;
//showmessage(FieldByName('MagID').AsString );
next;
end;
Close;
end;
end;
{通过名称获取怪物类型}
function GatMonRaceByName(Name: string): Integer;
var
I: Integer;
begin
Result := -1;
for I := 0 to High(g_pMonRaceInfo) do
begin
if g_pMonRaceInfo[I].szMonName = Name then
begin
Result := I;
Exit;
end;
end;
end;
{初始化类型信息}
procedure InitMonRaceInfo;
var
I: Integer;
begin
with DataManager.Query1 do
begin
Close;
sql.Clear;
sql.Add('SELECT Name, Race, RaceImg, Appr, Lvl, Undead, CoolEye, Exp, HP, MP, AC, MAC,' +
' DC, DCMAX, MC, SC, SPEED, HIT, WALK_SPD, WalkStep, WaLkWait, ATTACK_SPD FROM "Monster.DB" Monster');
open;
first;
SetLength(g_pMonRaceInfo, RecordCount);
g_nNumOfMonRaceInfo := RecordCount;
for I := 0 to RecordCount - 1 do
begin
// g_pMagicInfo[I] := TMagicInfo.Create;
g_pMonRaceInfo[I].nIndex := I;
g_pMonRaceInfo[I].szMonName := FieldByName('Name').AsString;
g_pMonRaceInfo[I].nMonRace := FieldByName('Race').AsInteger;
g_pMonRaceInfo[I].nRaceImg := FieldByName('RaceImg').AsInteger;
g_pMonRaceInfo[I].nCoolEye := FieldByName('CoolEye').AsInteger;
g_pMonRaceInfo[I].nAppear := FieldByName('Appr').AsInteger;
g_pMonRaceInfo[I].btUndead := FieldByName('Undead').AsInteger;
g_pMonRaceInfo[I].Level := FieldByName('Lvl').AsInteger;
g_pMonRaceInfo[I].HP := FieldByName('HP').AsInteger;
g_pMonRaceInfo[I].MP := FieldByName('MP').AsInteger;
g_pMonRaceInfo[I].AC := FieldByName('AC').AsInteger;
g_pMonRaceInfo[I].MAC := FieldByName('MAC').AsInteger;
g_pMonRaceInfo[I].DC := FieldByName('DC').AsInteger;
g_pMonRaceInfo[I].MC := FieldByName('MC').AsInteger;
g_pMonRaceInfo[I].SC := FieldByName('SC').AsInteger;
g_pMonRaceInfo[I].DCMax := FieldByName('DCMAX').AsInteger;
g_pMonRaceInfo[I].dwAttackSpeed := FieldByName('ATTACK_SPD').AsInteger;
g_pMonRaceInfo[I].WalkWait := FieldByName('WaLkWait').AsInteger;
g_pMonRaceInfo[I].WalkStep := FieldByName('WalkStep').AsInteger;
g_pMonRaceInfo[I].dwWalkSpeed := FieldByName('WALK_SPD').AsInteger;
g_pMonRaceInfo[I].Speed := FieldByName('SPEED').AsInteger;
g_pMonRaceInfo[I].Hit := FieldByName('HIT').AsInteger;
g_pMonRaceInfo[I].Exp := FieldByName('Exp').AsInteger;
g_pMonRaceInfo[I].wRaceIndex := I;
next;
end;
Close;
end;
end;
procedure InitStdItemSpecial; //初始化物品
var
I: Integer;
begin
with DataManager.Query1 do
begin
Close;
sql.Clear;
sql.Add('SELECT Idx, Name, Stdmode, Shape, Weight, Anicount, Source, Reserved,' +
' Looks, DuraMax, Ac, Ac2, Mac, Mac2, Dc, Dc2, Mc, Mc2, Sc, Sc2, Need, NeedLevel, Price,' +
' Stock FROM "StdItems.DB" Stditems');
open;
first;
SetLength(g_pStdItemSpecial, RecordCount);
g_nStdItemSpecial := RecordCount;
g_pStdItemHash := TStringHash.Create(RecordCount);
for I := 0 to RecordCount - 1 do
begin
g_pStdItemSpecial[I] := TStdItemSpecial.Create;
g_pStdItemSpecial[I].wNeed := FieldByName('Need').AsInteger;
g_pStdItemSpecial[I].wIndex := FieldByName('Idx').AsInteger;
g_pStdItemSpecial[I].wNeedLevel := FieldByName('NeedLevel').AsInteger;
g_pStdItemSpecial[I].dwStock := FieldByName('Stock').AsInteger;
g_pStdItemSpecial[I].dwLooks := FieldByName('Looks').AsInteger;
g_pStdItemSpecial[I].wDuraMax := FieldByName('DuraMax').AsInteger;
g_pStdItemSpecial[I].dwPrice := FieldByName('Price').AsInteger;
g_pStdItemSpecial[I].wReserved := FieldByName('Reserved').AsInteger;
// g_pStdItemSpecial[I]:=FieldByName('').AsInteger;
g_pStdItemSpecial[I].szName := FieldByName('Name').AsString;
g_pStdItemSpecial[I].wStdMode := FieldByName('Stdmode').AsInteger;
g_pStdItemSpecial[I].wShape := FieldByName('Shape').AsInteger;
g_pStdItemSpecial[I].wWeight := FieldByName('Weight').AsInteger;
g_pStdItemSpecial[I].wAniCount := FieldByName('Anicount').AsInteger;
g_pStdItemSpecial[I].wSource := FieldByName('Source').AsInteger;
g_pStdItemSpecial[I].wAC := FieldByName('Ac').AsInteger;
g_pStdItemSpecial[I].wAC2 := FieldByName('Ac2').AsInteger;
g_pStdItemSpecial[I].wMAC := FieldByName('Mac').AsInteger;
g_pStdItemSpecial[I].wMAC2 := FieldByName('Mac2').AsInteger;
g_pStdItemSpecial[I].wDC := FieldByName('Dc').AsInteger;
g_pStdItemSpecial[I].wDC2 := FieldByName('Dc2').AsInteger;
g_pStdItemSpecial[I].wMC := FieldByName('Mc').AsInteger;
g_pStdItemSpecial[I].wMC2 := FieldByName('Mc2').AsInteger;
g_pStdItemSpecial[I].wSC := FieldByName('Sc').AsInteger;
g_pStdItemSpecial[I].wSC2 := FieldByName('Sc2').AsInteger;
g_pStdItemHash.Add(FieldByName('Name').AsString, I);
//g_pMagicInfo[i].nIndex:=FieldByName('MagID').AsInteger;
//showmessage(FieldByName('MagID').AsString );
next;
end;
Close;
end;
end;
{procedure InitStdItemEtcInfo;
var
I: Integer;
szQuery: TStrings;
begin
szQuery := TStringList.Create;
szQuery.Clear;
szQuery.Add('SELECT COUNT(*) AS FLD_COUNT FROM TBL_STDITEM_ETC');
with DataManager.ADOQuerySQL do
begin
SQL := szQuery;
ExecSQL;
Open;
First;
g_nStdItemEtc := StrToInt(FieldByName('FLD_COUNT').AsString);
Close;
end; // with
if g_nStdItemEtc < 0 then
begin
Exit;
end;
SetLength(g_pStdItemEtc, g_nStdItemEtc);
szQuery.Clear;
szQuery.Add('SELECT * FROM TBL_STDITEM_ETC ORDER BY FLD_INDEX');
with DataManager.ADOQuerySQL do
begin
SQL := szQuery;
ExecSQL;
Open;
First;
for I := 0 to g_nStdItemEtc - 1 do // Iterate
begin
g_pStdItemEtc[I] := TStdItem.Create;
g_pStdItemEtc[I].szName := FieldByName('FLD_NAME').AsString;
g_pStdItemEtc[I].wStdMode := StrToInt(FieldByName('FLD_STDMODE').AsString);
g_pStdItemEtc[I].wShape := StrToInt(FieldByName('FLD_SHAPE').AsString);
g_pStdItemEtc[I].wWeight := StrToInt(FieldByName('FLD_WEIGHT').AsString);
g_pStdItemEtc[I].dwLooks := StrToInt(FieldByName('FLD_LOOKS').AsString);
g_pStdItemEtc[I].wDuraMax := StrToInt(FieldByName('FLD_VAL1').AsString);
g_pStdItemEtc[I].dwRSource:= StrToInt(FieldByName('FLD_VAL2').AsString);
g_pStdItemEtc[I].dwPrice := StrToInt(FieldByName('FLD_PRICE').AsString);
Next;
end; // for
Close;
end; // with
end;
}
{初始化商人信息}
procedure InitMerchantInfo;
var
I, K: Integer;
MerChantStrings, temp: Tstrings;
MerChantStr: string;
Path: string;
begin
MerChantStrings := TStringList.Create;
K := 0;
try
Path := ExtractFilePath(Application.ExeName);
if Path[Length(Path)] <> '\' then
Path := Path + '\';
MerChantStrings.LoadFromFile('.\Envir\MerChant.txt');
SetLength(g_pMerchantInfo, MerChantStrings.COunt);
///设置g_pmeovmapeventinfo数组的长度,一开始设置得较长;
for I := 0 to MerChantStrings.COunt - 1 do
begin
MerChantStr := Trim(MerChantStrings[I]);
if Length(MerChantStr) <> 0 then ///
if MerChantStr[1] <> ';' then
begin
temp := SplitStringByChar(MerChantStr, [#1..' ']);
//以指定的字符分割字符串
if temp.COunt < 8 then
Continue;
g_pMerchantInfo[K].idStr := temp[0];
g_pMerchantInfo[K].szMapName := temp[1];
g_pMerchantInfo[K].nPosX := StrToInt(temp[2]);
g_pMerchantInfo[K].nPosY := StrToInt(temp[3]);
g_pMerchantInfo[K].szNPCName := temp[4];
g_pMerchantInfo[K].sFace := StrToInt(temp[5]);
g_pMerchantInfo[K].sBody := StrToInt(temp[6]);
g_pMerchantInfo[K].sGender := StrToInt(temp[7]);
Inc(K);
temp.Free;
end;
end;
SetLength(g_pMerchantInfo, K); //重新设置长度,缩短数组的大小
g_nNumOfMerchantInfo := K;
finally
MerChantStrings.Free;
end;
end;
{}
procedure InitMoveMapEventInfo; ///初始化移动地图事件信息
var
I, K, flag: Integer;
MapInfoStrings, temp: Tstrings;
MapInfoStr: string;
begin
MapInfoStrings := TStringList.Create;
K := 0;
try
MapInfoStrings.LoadFromFile('.\Envir\MapInfo.txt');
SetLength(g_pMoveMapEventInfo, MapInfoStrings.COunt);
///设置g_pmeovmapeventinfo数组的长度,一开始设置得较长;
for I := 0 to MapInfoStrings.COunt - 1 do
begin
MapInfoStr := Trim(MapInfoStrings[I]);
if Length(MapInfoStr) <> 0 then ///
if MapInfoStr[1] <> ';' then
begin
flag := pos('->', MapInfoStr);
if flag > 0 then
begin
Insert(' ', MapInfoStr, flag);
Insert(' ', MapInfoStr, flag + 3);
temp := SplitStringByChar(MapInfoStr, [#1..' ', ',', ':', '.']);
g_pMoveMapEventInfo[K].szSMapFileName := temp[0];
g_pMoveMapEventInfo[K].szDMapFileName := temp[4];
g_pMoveMapEventInfo[K].nSX := StrToInt(temp[1]);
g_pMoveMapEventInfo[K].nSY := StrToInt(temp[2]);
g_pMoveMapEventInfo[K].nDX := StrToInt(temp[5]);
g_pMoveMapEventInfo[K].nDY := StrToInt(temp[6]);
g_pMoveMapEventInfo[K].fIsOpen := False;
K := K + 1;
temp.Free;
end;
end;
end;
SetLength(g_pMoveMapEventInfo, K);
g_nNumOfMoveMapEventInfo := K;
finally
MapInfoStrings.Free;
end;
end;
{初始化地图,并返回地图的信息}
function InitMapInfo(nServerIndex: Integer): MAPINFO_RCD_ARRAY; //初始化地图信息;
var
MapInfoStrings, tempStrings: Tstrings;
MapInfoStr: string;
Attribute: string;
I, K, flag, tempflag: Integer;
pMapInfo: MAPINFO_RCD_ARRAY;
begin
MapInfoStrings := TStringList.Create;
K := 0;
try
MapInfoStrings.LoadFromFile('.\Envir\mapinfo.txt');
SetLength(pMapInfo, MapInfoStrings.COunt);
for I := 0 to MapInfoStrings.COunt - 1 do
begin
MapInfoStr := Trim(MapInfoStrings[I]);
if Length(MapInfoStr) <> 0 then
if MapInfoStr[1] <> ';' then
begin
flag := pos(']', MapInfoStr);
if flag <> 0 then
begin
tempflag := pos('[', MapInfoStr);
tempStrings := SplitStringByChar(Copy(MapInfoStr, tempflag + 1, flag
- tempflag - 1), [#1..' ']);
Attribute := Trim(midbstr(MapInfoStr, flag + 1,
Length(MapInfoStr)));
//if nServerIndex=strtoint(tempStrings[2]) then
begin
pMapInfo[K].szMapFileName := tempStrings[0];
pMapInfo[K].szMapName := tempStrings[1];
pMapInfo[K].Attribute := Attribute;
K := K + 1;
end;
tempStrings.Free;
end;
end;
end;
SetLength(pMapInfo, K);
g_nNumOfMapInfo := K;
Result := pMapInfo;
finally
MapInfoStrings.Free;
end;
end;
{通过魔法ID获取魔法信息}
function GetMagicInfo(nMagicID: Integer): TMagicInfo;
var
I: Integer;
begin
if g_pMagicInfo[nMagicID].Def.MagicID = nMagicID then
begin
Result := g_pMagicInfo[nMagicID];
Exit;
end;
for I := 0 to g_nNumOfMagicInfo - 1 do
begin
if g_pMagicInfo[I].Def.MagicID = nMagicID then
begin
Result := g_pMagicInfo[I];
Exit;
end;
end;
Result := nil;
end;
{}
function GetMonGenInfo(pszMonName: string): PMONSTERGENINFO_RCD;
var
I,
nCmpLen,
nLen: Integer;
begin
nLen := StrLen(PChar(pszMonName));
for I := 0 to g_nNumOfMonGenInfo - 1 do // Iterate
begin
nCmpLen := StrLen(@g_pMonGenInfo[I].szMonName[1]);
if nCmpLen = nLen then
begin
if LeftBStr(g_pMonGenInfo[I].szMonName,
StrLen(@g_pMonGenInfo[I].szMonName[1])) = LeftBStr(pszMonName,
StrLen(@pszMonName[1])) then
begin
Result := @g_pMonGenInfo[I];
end;
end;
end; // for
Result := nil;
end;
function GetMonRaceInfo(pszMonName: string): PMONRACEINFO_RCD;
var
I,
nCmpLen,
nLen: Integer;
begin
Result := nil;
nLen := StrLen(PChar(pszMonName));
for I := 0 to g_nNumOfMonRaceInfo - 1 do // Iterate
begin
nCmpLen := StrLen(@g_pMonRaceInfo[I].szMonName[1]);
if nCmpLen = nLen then
begin
if g_pMonRaceInfo[I].szMonName = pszMonName then
begin
Result := @g_pMonRaceInfo[I];
Break;
end;
end;
end; // for
end;
//**************************************************************************************
// TItem Class Members
//**************************************************************************************
{}
function TItem.GetUpgrade(nCount, nRandom: Integer): Integer;
var
I,
nResult: Integer;
begin
nResult := 0;
for I := 0 to nCount - 1 do
begin
if (Random(32767) mod nRandom) = 0 then
begin
Inc(nResult);
end
else
begin
Break;
end;
end;
Result := nResult;
end;
//**************************************************************************************
// TStdItem Class Members
//**************************************************************************************
procedure tStdItem.GetStandardItem(lpClientItemRcd: PCLIENTITEM_RCD);
begin
CopyMemory(@lpClientItemRcd^.tStdItem.szName[1], @szName[1], 20);
lpClientItemRcd^.tStdItem.btStdMode := Byte(wStdMode);
lpClientItemRcd^.tStdItem.btShape := Byte(wShape);
lpClientItemRcd^.tStdItem.btWeight := Byte(wWeight);
lpClientItemRcd^.tStdItem.btAniCount := 0;
lpClientItemRcd^.tStdItem.btSource := 0;
lpClientItemRcd^.tStdItem.wLooks := Word(dwLooks);
lpClientItemRcd^.tStdItem.wDuraMax := Word(wDuraMax);
lpClientItemRcd^.tStdItem.btNeed := 0;
lpClientItemRcd^.tStdItem.btNeedLevel := 0;
lpClientItemRcd^.tStdItem.nPrice := dwPrice;
end;
procedure tStdItem.GetUpgradeStdItem(lpClientItemRcd: PCLIENTITEM_RCD;
lpUserItemRcd: PUSERITEM_RCD);
begin
// Do nothing Now
end;
//**************************************************************************************
// TStdItemSpecial Class Members
//**************************************************************************************
procedure TStdItemSpecial.GetStandardItem(lpClientItemRcd: PTCLIENTITEM);
begin
lpClientItemRcd.s.Name := szName;
lpClientItemRcd^.s.StdMode := Byte(wStdMode);
lpClientItemRcd^.s.Shape := Byte(wShape);
lpClientItemRcd^.s.Weight := Byte(wWeight);
lpClientItemRcd^.s.AniCount := Byte(wAniCount);
lpClientItemRcd^.s.source := Byte(wSource);
lpClientItemRcd^.s.Looks := Word(dwLooks);
lpClientItemRcd^.s.DuraMax := Word(wDuraMax);
lpClientItemRcd^.s.Need := Byte(wNeed);
lpClientItemRcd^.s.NeedLevel := Byte(wNeedLevel);
lpClientItemRcd^.s.Price := dwPrice;
lpClientItemRcd^.s.AC := MAKEWORD(wAC, wAC2);
lpClientItemRcd^.s.MAC := MAKEWORD(wMAC, wMAC2);
lpClientItemRcd^.s.DC := MAKEWORD(wDC, wDC2);
lpClientItemRcd^.s.MC := MAKEWORD(wMC, wMC2);
lpClientItemRcd^.s.SC := MAKEWORD(wSC, wSC2);
lpClientItemRcd^.s.bNeed := wNeed;
lpClientItemRcd^.s.NeedIdentify := wReserved;
lpClientItemRcd^.s.SpecialPower := wReserved;
lpClientItemRcd.Dura := wDuraMax;
lpClientItemRcd.DuraMax := wDuraMax;
end;
procedure TStdItemSpecial.GetUpgradeStdItem(lpClientItemRcd: PCLIENTITEM_RCD;
lpUserItemRcd: PUSERITEM_RCD);
begin
case btType of //
0:
begin
lpClientItemRcd^.tStdItem.wDC := MAKEWORD(wDC, wDC2 +
lpUserItemRcd^.btValue[0]);
lpClientItemRcd^.tStdItem.wMC := MAKEWORD(wMC, wMC2 +
lpUserItemRcd^.btValue[1]);
lpClientItemRcd^.tStdItem.wSC := MAKEWORD(wSC, wSC2 +
lpUserItemRcd^.btValue[2]);
lpClientItemRcd^.tStdItem.wAC := MAKEWORD(wAC +
lpUserItemRcd^.btValue[3], wAC2 + lpUserItemRcd^.btValue[5]);
lpClientItemRcd^.tStdItem.wMAC := MAKEWORD(wMAC +
lpUserItemRcd^.btValue[4], wMAC2 + lpUserItemRcd^.btValue[6]);
lpClientItemRcd^.tStdItem.btSource := lpUserItemRcd^.btValue[7];
end;
1:
begin
lpClientItemRcd^.tStdItem.wAC := MAKEWORD(wAC, wAC2 +
lpUserItemRcd^.btValue[0]);
lpClientItemRcd^.tStdItem.wMAC := MAKEWORD(wMAC, wMAC2 +
lpUserItemRcd^.btValue[1]);
lpClientItemRcd^.tStdItem.wDC := MAKEWORD(wDC, wDC2 +
lpUserItemRcd^.btValue[2]);
lpClientItemRcd^.tStdItem.wMC := MAKEWORD(wMC, wMC2 +
lpUserItemRcd^.btValue[3]);
lpClientItemRcd^.tStdItem.wSC := MAKEWORD(wSC, wSC2 +
lpUserItemRcd^.btValue[4]);
end;
2:
begin
lpClientItemRcd^.tStdItem.wAC := MAKEWORD(wAC, wAC2 +
lpUserItemRcd^.btValue[0]);
lpClientItemRcd^.tStdItem.wMAC := MAKEWORD(wMAC, wMAC2 +
lpUserItemRcd^.btValue[1]);
lpClientItemRcd^.tStdItem.wDC := MAKEWORD(wDC, wDC2 +
lpUserItemRcd^.btValue[2]);
lpClientItemRcd^.tStdItem.wMC := MAKEWORD(wMC, wMC2 +
lpUserItemRcd^.btValue[3]);
lpClientItemRcd^.tStdItem.wSC := MAKEWORD(wSC, wSC2 +
lpUserItemRcd^.btValue[4]);
end;
else
begin
lpClientItemRcd^.tStdItem.wAC := 0;
lpClientItemRcd^.tStdItem.wMAC := 0;
lpClientItemRcd^.tStdItem.wDC := 0;
lpClientItemRcd^.tStdItem.wMC := 0;
lpClientItemRcd^.tStdItem.wSC := 0;
lpClientItemRcd^.tStdItem.btSource := 0;
end;
end; //case
end;
procedure TStdItemSpecial.UpgradeRandomItem(btValue: PChar; var nDura, nDuraMax:
Word);
var
nUpgrade,
nIncp,
nVal: Integer;
begin
case btType of //
0:
begin
nUpgrade := GetUpgrade(12, 15);
if (Random(32767) mod 15) = 0 then
begin
btValue[0] := Char(1 + nUpgrade); // DC
end;
nUpgrade := GetUpgrade(12, 15);
if (Random(32767) mod 20) = 0 then
begin
nIncp := (1 + nUpgrade) div 3;
if nIncp > 0 then
begin
if (Random(32767) mod 3) <> 0 then
begin
btValue[6] := Char(nIncp);
end
else
begin
btValue[6] := Char(10 + nIncp);
end;
end;
end;
nUpgrade := GetUpgrade(12, 15);
if (Random(32767) mod 15) = 0 then
begin
btValue[1] := Char(1 + nUpgrade); // MC
end;
nUpgrade := GetUpgrade(12, 15);
if (Random(32767) mod 15) = 0 then
begin
btValue[2] := Char(1 + nUpgrade); // SC
end;
nUpgrade := GetUpgrade(12, 15);
if (Random(32767) mod 24) = 0 then
begin
btValue[5] := Char(1 + nUpgrade div 2);
end;
nUpgrade := GetUpgrade(12, 12);
if (Random(32767) mod 3) < 2 then
begin
nVal := (1 + nUpgrade) * 2000;
nDuraMax := Min(65000, nDuraMax + nVal);
nDura := Min(65000, nDura + nVal);
end;
nUpgrade := GetUpgrade(12, 15);
if (Random(32767) mod 10) = 0 then
begin
btValue[7] := Char(1 + nUpgrade div 2);
end;
end;
1:
begin
nUpgrade := GetUpgrade(6, 15);
if (Random(32767) mod 40) = 0 then
begin
btValue[0] := Char(1 + nUpgrade); // AC
end;
nUpgrade := GetUpgrade(6, 15);
if (Random(32767) mod 40) = 0 then
begin
btValue[1] := Char(1 + nUpgrade); // MAC
end;
nUpgrade := GetUpgrade(6, 20);
if (Random(32767) mod 40) = 0 then
begin
btValue[2] := Char(1 + nUpgrade); // DC
end;
nUpgrade := GetUpgrade(6, 20);
if (Random(32767) mod 40) = 0 then
begin
btValue[3] := Char(1 + nUpgrade); // MC
end;
nUpgrade := GetUpgrade(6, 20);
if (Random(32767) mod 40) = 0 then
begin
btValue[4] := Char(1 + nUpgrade); // SC
end;
nUpgrade := GetUpgrade(6, 10);
if (Random(32767) mod 8) < 6 then
begin
nVal := (1 + nUpgrade) * 2000;
nDuraMax := Min(65000, nDuraMax + nVal);
nDura := Min(65000, nDura + nVal);
end;
end;
2:
begin
nUpgrade := GetUpgrade(6, 30);
if (Random(32767) mod 60) = 0 then
begin
btValue[0] := Char(1 + nUpgrade); // AC(HIT)
end;
nUpgrade := GetUpgrade(6, 30);
if (Random(32767) mod 60) = 0 then
begin
btValue[1] := Char(1 + nUpgrade); // MAC(SPEED)
end;
nUpgrade := GetUpgrade(6, 20);
if (Random(32767) mod 30) = 0 then
begin
btValue[2] := Char(1 + nUpgrade); // DC
end;
nUpgrade := GetUpgrade(6, 20);
if (Random(32767) mod 30) = 0 then
begin
btValue[3] := Char(1 + nUpgrade); // MC
end;
nUpgrade := GetUpgrade(6, 20);
if (Random(32767) mod 30) = 0 then
begin
btValue[4] := Char(1 + nUpgrade); // SC
end;
nUpgrade := GetUpgrade(6, 12);
if (Random(32767) mod 20) < 15 then
begin
nVal := (1 + nUpgrade) * 1000;
nDuraMax := Min(65000, nDuraMax + nVal); //DURA Stuffs
nDura := Min(65000, nDura + nVal);
end;
end;
end; //case
end;
procedure TStdItemSpecial.ApplyItemParameters(m_pAddAbility:
POBJECTADDABILITY_RCD);
begin
case btType of //
0:
begin
m_pAddAbility^.Hit := m_pAddAbility^.Hit + wAC2;
if wMAC2 > 10 then
begin
m_pAddAbility^.HitSpeed := m_pAddAbility^.HitSpeed + wMAC2 - 10;
end
else
begin
m_pAddAbility^.HitSpeed := m_pAddAbility^.HitSpeed - wMAC2;
end;
m_pAddAbility^.Luck := m_pAddAbility^.Luck + wAC;
m_pAddAbility^.UnLuck := m_pAddAbility^.UnLuck + wMAC;
end;
1:
begin
m_pAddAbility^.AC := MAKEWORD(LOBYTE(m_pAddAbility^.AC) + wAC,
HIBYTE(m_pAddAbility^.AC) + wAC2);
m_pAddAbility^.MAC := MAKEWORD(LOBYTE(m_pAddAbility^.MAC) + wMAC,
HIBYTE(m_pAddAbility^.MAC) + wMAC2);
end;
2:
begin
case wStdMode of
21:
begin
m_pAddAbility^.AntiMagic := m_pAddAbility^.AntiMagic + wAC2;
m_pAddAbility^.UnLuck := m_pAddAbility^.UnLuck + wMAC;
m_pAddAbility^.Luck := m_pAddAbility^.Luck + wMAC2;
end;
22,
41:
begin
m_pAddAbility^.Hit := m_pAddAbility^.Hit + wAC2;
m_pAddAbility^.Speed := m_pAddAbility^.Speed + wMAC2;
end;
23:
begin
m_pAddAbility^.HealthRecover := m_pAddAbility^.HealthRecover +
wAC2;
m_pAddAbility^.SpellRecover := m_pAddAbility^.SpellRecover +
wMAC2;
m_pAddAbility^.HitSpeed := m_pAddAbility^.HitSpeed + wAC;
m_pAddAbility^.HitSpeed := m_pAddAbility^.HitSpeed - wMAC;
end;
32:
begin
m_pAddAbility^.AntiPoison := m_pAddAbility^.AntiPoison + wAC2;
m_pAddAbility^.PoisonRecover := m_pAddAbility^.PoisonRecover +
wMAC2;
m_pAddAbility^.HitSpeed := m_pAddAbility^.HitSpeed + wAC;
m_pAddAbility^.HitSpeed := m_pAddAbility^.HitSpeed - wMAC;
end;
else
begin
m_pAddAbility^.AC := MAKEWORD(LOBYTE(m_pAddAbility^.AC) + wAC,
HIBYTE(m_pAddAbility^.AC) + wAC2);
m_pAddAbility^.MAC := MAKEWORD(LOBYTE(m_pAddAbility^.MAC) + wMAC,
HIBYTE(m_pAddAbility^.MAC) + wMAC2);
end;
end;
end;
end; // case
m_pAddAbility^.DC := wDC + wDC2;
m_pAddAbility^.MC := wMC + wMC2;
m_pAddAbility^.SC := wSC + wSC2;
end;
//**************************************************************************************
// TMagicInfo Class Members
//**************************************************************************************
function TMagicInfo.GetPower13(nPwr: Integer; nLevel: Integer): Integer;
var
p1,
p2: Single;
begin
p1 := nPwr / 3;
p2 := nPwr - p1;
with Def do
begin
if (defmaxpower - MinPower) > 0 then
begin
Result := Round(p1 + p2 / 4 * (nLevel + 1) + MinPower + (Random(32767) mod
(defmaxpower - MinPower)));
Exit;
end
else
begin
Result := Round(p1 + p2 / 4 * (nLevel + 1) + MinPower);
Exit;
end;
end;
end;
function TMagicInfo.CheckMagicLevelup(pCharObject: TObject; lptMagicRcd:
PHUMANMAGIC_RCD): Boolean; //提升魔法等级?
var
nLevel: Integer;
begin
if (Integer(lptMagicRcd^.btLevel) >= 0) and (Integer(lptMagicRcd^.btLevel) <=
3) then
begin
nLevel := Integer(lptMagicRcd^.btLevel);
end
else
begin
nLevel := 0;
end;
if Integer(lptMagicRcd^.btLevel) < 3 then
begin
if lptMagicRcd^.nCurrTrain >= Def.MaxTrain[nLevel] then
begin
if Integer(lptMagicRcd^.btLevel) < 3 then
begin
lptMagicRcd^.nCurrTrain := lptMagicRcd^.nCurrTrain -
Def.MaxTrain[nLevel];
lptMagicRcd^.btLevel := Char(Integer(lptMagicRcd^.btLevel) + 1);
TCharObject(pCharObject).UpdateDelayProcessCheckParam1(TCharObject(pCharObject),
RM_MAGIC_LVEXP, 0, lptMagicRcd^.nCurrTrain,
Integer(lptMagicRcd^.btLevel),
lptMagicRcd^.btMagicID, '', 800);
end
else
begin
lptMagicRcd^.nCurrTrain := Def.MaxTrain[nLevel];
end;
Result := True;
Exit;
end;
end;
Result := False;
end;
function TMagicInfo.MPow: Integer;
begin
if (Def.defmaxpower - Def.MinPower) > 0 then
begin
Result := Def.MinPower + (Random(32767) mod (Def.defmaxpower -
Def.MinPower));
end
else
begin
Result := Def.MinPower;
end;
end;
function TMagicInfo.GetSpellPoint(nLevel: Integer): Integer;
begin
Result := Round(Def.spell / 4 * (nLevel + 1)) + Def.defspell;
end;
function TMagicInfo.GetPower(nPwr, nLevel: Integer): Integer;
begin
if (Def.defmaxpower - Def.MinPower) > 0 then
begin
Result := Round(nPwr / 4 * (nLevel + 1)) + Def.MinPower + (Random(32767) mod
(Def.defmaxpower - Def.MinPower));
end
else
begin
Result := Round(nPwr / 4 * (nLevel + 1)) + Def.MinPower;
end;
end;
//**************************************************************************************
// TMirMap Class Members
//**************************************************************************************
constructor TMirMap.Create;
begin
m_HumCount := 0;
m_pMapCellInfo := nil;
end;
destructor TMirMap.Destroy;
begin
FreeMapData;
end;
function TMirMap.IsValidObject(nX, nY, nCheckRange: Integer; pCharObject:
TObject): Boolean;
var
I: Integer;
iX, iY: Integer;
pMapCellInfo: PMAPCELLINFO_RCD;
pOSObject: POSOBJECT_RCD;
begin
for iX := nX - nCheckRange to nX + nCheckRange do // Iterate
begin
for iY := nY - nCheckRange to nY + nCheckRange do // Iterate
begin
pMapCellInfo := GetMapCellInfo(iX, iY);
if pMapCellInfo <> nil then
begin
with pMapCellInfo^.m_xpObjectList.LockList do
begin
for I := 0 to COunt - 1 do // Iterate
begin
pOSObject := POSOBJECT_RCD(items[I]);
if pOSObject^.btType = OS_MOVINGOBJECT then
begin
pCharObject := TCharObject(pOSObject^.pObject);
if pCharObject <> nil then
begin
Result := True;
pMapCellInfo^.m_xpObjectList.UnlockList;
Exit;
end;
end;
end; // for
end; // with
pMapCellInfo^.m_xpObjectList.UnlockList;
end;
end; // for
end; // for
Result := False;
end;
function TMirMap.LoadMapData(var pszName: string): Boolean;
var
I: Integer;
hofFile: Integer;
dwReadLen: LongWord;
nMapSize: Integer;
pstCellInfo: array of TCELLINFO_RCD;
szMapFileName,
szPath: string;
begin
szMapFileName := g_IniConfiguration.MapFileLoc + '\' + pszName;
hofFile := FileOpen(szMapFileName, fmOpenRead or fmShareDenyNone);
if hofFile <> 0 then
begin
FreeMapData;
FileRead(hofFile, PChar(@m_stMapFH)^, SizeOf(TMAPFILEHEADER_RCD));
nMapSize := m_stMapFH.shWidth * m_stMapFH.shHeight;
// FileSeek(hofFile, sizeof(TTILEINFO_RCD)*(nMapSize shr 2), 1);
SetLength(pstCellInfo, nMapSize);
FileRead(hofFile, PChar(pstCellInfo)^, SizeOf(TCELLINFO_RCD) * nMapSize);
FileClose(hofFile);
SetLength(m_pMapCellInfo, nMapSize);
for I := 0 to nMapSize - 1 do // Iterate
begin
if ((pstCellInfo[I].BkImg and $8000) + (pstCellInfo[I].FrImg and $8000)) >
0 then
m_pMapCellInfo[I].CanMove := 1
else
m_pMapCellInfo[I].CanMove := 0;
m_pMapCellInfo[I].m_chFlag := pstCellInfo[I].DoorIndex;
m_pMapCellInfo[I].m_sLightNEvent := pstCellInfo[I].light;
m_pMapCellInfo[I].m_xpObjectList := nil;
end; // for
pstCellInfo := nil;
g_xMirMapList.Add(self);
Result := True;
Exit;
end;
Result := False;
end;
procedure TMirMap.FreeMapData;
var
nMapSize: Integer;
I: Integer;
begin
if m_pMapCellInfo <> nil then
begin
nMapSize := m_stMapFH.shWidth * m_stMapFH.shHeight;
for I := 0 to nMapSize - 1 do // Iterate
begin
m_pMapCellInfo[I].m_xpObjectList.Clear;
m_pMapCellInfo[I].m_xpObjectList := nil;
end; // for
end;
m_pMapCellInfo := nil;
end;
function TMirMap.CanMove(nX, nY: Integer; fFlag: Boolean): Boolean;
var
I: Integer;
fRet: Boolean;
pMapCellInfo: PMAPCELLINFO_RCD;
pCharObject: TCharObject;
pOSObject: POSOBJECT_RCD;
begin
fRet := False;
pMapCellInfo := GetMapCellInfo(nX, nY);
if pMapCellInfo = nil then
begin
Result := False;
Exit;
end;
if pMapCellInfo.CanMove > 0 then
begin
Result := False;
Exit;
end;
if pMapCellInfo <> nil then
begin
fRet := True;
if pMapCellInfo^.m_xpObjectList <> nil then
begin
with pMapCellInfo^.m_xpObjectList.LockList do
begin
for I := 0 to COunt - 1 do // Iterate
begin
pOSObject := POSOBJECT_RCD(items[I]);
if pOSObject^.btType = OS_MOVINGOBJECT then
begin
pCharObject := TCharObject(pOSObject^.pObject);
if (pCharObject.m_fIsDead = False) and (pCharObject.m_fInspector =
False) and (pCharObject.m_fHideMode = False) then
begin
if fFlag = False then
begin
fRet := False;
Break;
end;
end;
end;
end; // for
end; // with
pMapCellInfo^.m_xpObjectList.UnlockList;
end;
end;
Result := fRet;
end;
function TMirMap.CheckDoorEvent(nX, nY: Integer; var nEvent: Integer): Integer;
var
pMapCellInfo: PMAPCELLINFO_RCD;
begin
pMapCellInfo := GetMapCellInfo(nX, nY);
if pMapCellInfo <> nil then
begin
if (pMapCellInfo^.m_sLightNEvent and $2) > 0 then // Door Event
begin
nEvent := (pMapCellInfo^.m_sLightNEvent and $3FFF) shr 4;
if (pMapCellInfo^.m_sLightNEvent and $8) > 0 then // Event
begin
if (pMapCellInfo^.m_sLightNEvent and $C000) > 0 then
begin
Result := _DOOR_MAPMOVE_BACK;
Exit;
end
else
begin
Result := _DOOR_MAPMOVE_FRONT;
Exit;
end;
end;
Result := _DOOR_OPEN;
Exit;
end;
end;
Result := _DOOR_NOT;
end;
function TMirMap.CheckEvent(nX, nY: Integer): Integer;
var
pMapCellInfo: PMAPCELLINFO_RCD;
begin
pMapCellInfo := GetMapCellInfo(nX, nY);
if pMapCellInfo <> nil then
begin
if (pMapCellInfo^.m_sLightNEvent and $4) > 0 then // Event
begin
Result := (pMapCellInfo^.m_sLightNEvent and $C000) shr 4;
Exit;
end;
end;
Result := 0;
end;
function TMirMap.MoveToMovingObject(nX, nY, nTargetX, nTargetY: Integer;
pCharObject: TObject): Boolean;
var
fRet: Boolean;
begin
fRet := False;
if RemoveObject(nX, nY, OS_MOVINGOBJECT, pCharObject) then
begin
if AddNewObject(nTargetX, nTargetY, OS_MOVINGOBJECT, pCharObject) then
fRet := True
else
fRet := False;
end
else
fRet := False;
Result := fRet;
end;
function TMirMap.RemoveObject(nX, nY: Integer; btType: Byte; pRemoveObject:
Pointer): Boolean;
var
I: Integer;
pMapCellInfo: PMAPCELLINFO_RCD;
pOSObject: POSOBJECT_RCD;
pCharObject: TCharObject;
begin
pMapCellInfo := GetMapCellInfo(nX, nY);
if pMapCellInfo <> nil then
begin
if pMapCellInfo^.m_xpObjectList = nil then
begin
Result := False;
Exit;
end;
with pMapCellInfo^.m_xpObjectList.LockList do
begin
for I := 0 to COunt - 1 do // Iterate
begin
pOSObject := POSOBJECT_RCD(items[I]);
if pOSObject <> nil then
begin
if (pOSObject^.pObject = pRemoveObject) and (pOSObject^.btType =
btType) then
begin
Delete(I);
Result := True;
if btType = OS_MOVINGOBJECT then
begin
pCharObject := TCharObject(pOSObject^.pObject);
if pCharObject.m_wObjectType = _OBJECT_HUMAN then
Dec(m_HumCount);
end;
pMapCellInfo^.m_xpObjectList.UnlockList;
Exit;
end;
end;
end; // for
end; // with
pMapCellInfo^.m_xpObjectList.UnlockList;
end;
Result := False;
end;
function TMirMap.AddNewObject(nX, nY: Integer; btType: Byte; pAddObject:
Pointer): Boolean;
var
pMapCellInfo: PMAPCELLINFO_RCD;
pOSObject: POSOBJECT_RCD;
pCharObject: TCharObject;
begin
pMapCellInfo := GetMapCellInfo(nX, nY);
if pMapCellInfo <> nil then
begin
if (pMapCellInfo^.CanMove = 0) then
begin
if pMapCellInfo^.m_xpObjectList = nil then
begin
pMapCellInfo^.m_xpObjectList := TThreadList.Create;
end;
New(pOSObject);
pOSObject^.btType := btType;
pOSObject^.pObject := pAddObject;
pOSObject^.dwAddTime := GetTickCount;
if btType = OS_MOVINGOBJECT then
begin
pCharObject := TCharObject(pOSObject^.pObject);
if pCharObject.m_wObjectType = _OBJECT_HUMAN then
Inc(m_HumCount);
end;
pMapCellInfo^.m_xpObjectList.Add(pOSObject);
Result := True;
Exit;
end;
end;
Result := False;
end;
function TMirMap.GetObject(nX, nY: Integer): TObject;
var
I: Integer;
pMapCellInfo: PMAPCELLINFO_RCD;
pOSObject: POSOBJECT_RCD;
pCharObject: TCharObject;
begin
pMapCellInfo := GetMapCellInfo(nX, nY);
if pMapCellInfo <> nil then
begin
{ if (Integer(pMapCellInfo^.m_chFlag) and $1) = 0 then
begin
Result := nil;
Exit;
end;
}
if pMapCellInfo^.m_xpObjectList <> nil then
begin
with pMapCellInfo^.m_xpObjectList.LockList do
begin
for I := 0 to COunt - 1 do // Iterate
begin
pOSObject := items[I];
if pOSObject <> nil then
begin
if pOSObject^.btType = OS_MOVINGOBJECT then
begin
pCharObject := TCharObject(pOSObject^.pObject);
if (pCharObject.m_fIsDead = False) and (pCharObject.m_fIsGhost =
False) then
begin
Result := pCharObject;
pMapCellInfo^.m_xpObjectList.UnlockList;
Exit;
end;
end;
end;
end; // for
end; // with
pMapCellInfo^.m_xpObjectList.UnlockList;
end;
end;
Result := nil;
end;
procedure TMirMap.GetMapObject(nX, nY, nArea: Integer; var pList: TThreadList);
var
I: Integer;
X, Y: Integer;
nStartX,
nEndX,
nStartY,
nEndY: Integer;
pOSObject: POSOBJECT_RCD;
pMapCellInfo: PMAPCELLINFO_RCD;
pCharObject: TCharObject;
begin
nStartX := nX - nArea;
nEndX := nX + nArea;
nStartY := nY - nArea;
nEndY := nY + nArea;
for X := nStartX to nEndX do
begin
for Y := nStartY to nEndY do
begin
pMapCellInfo := GetMapCellInfo(X, Y);
if pMapCellInfo <> nil then
begin
if pMapCellInfo^.m_xpObjectList <> nil then
begin
with pMapCellInfo^.m_xpObjectList.LockList do
begin
for I := 0 to COunt - 1 do // Iterate
begin
pOSObject := items[I];
if pOSObject^.btType = OS_MOVINGOBJECT then
begin
pCharObject := TCharObject(pOSObject^.pObject);
if (pCharObject.m_fIsGhost = False) and (pCharObject.m_fIsDead =
False) then
begin
pList.Add(pCharObject);
end;
end;
end; // for
end; // with
pMapCellInfo^.m_xpObjectList.UnlockList;
end;
end;
end;
end;
end;
procedure TMirMap.GetAllObject(nX, nY: Integer; var pList: TThreadList);
var
I: Integer;
pOSObject: POSOBJECT_RCD;
pMapCellInfo: PMAPCELLINFO_RCD;
pCharObject: TCharObject;
begin
pMapCellInfo := GetMapCellInfo(nX, nY);
if pMapCellInfo <> nil then
begin
if pMapCellInfo^.m_xpObjectList <> nil then
begin
with pMapCellInfo^.m_xpObjectList.LockList do
begin
for I := 0 to COunt - 1 do // Iterate
begin
pOSObject := items[I];
if pOSObject^.btType = OS_MOVINGOBJECT then
begin
pCharObject := TCharObject(pOSObject^.pObject);
if (pCharObject.m_fIsGhost = False) and (pCharObject.m_fIsDead =
False) then
begin
pList.Add(pCharObject);
end;
end;
end; // for
end; // with
pMapCellInfo^.m_xpObjectList.UnlockList;
end;
end; // if (PMAPCELLINFO_RCD)
end;
function TMirMap.GetDupCount(nX, nY: Integer): Integer;
var
I: Integer;
pMapCellInfo: PMAPCELLINFO_RCD;
pCharObject: TCharObject;
pOSObject: POSOBJECT_RCD;
nCount: Integer;
begin
pMapCellInfo := GetMapCellInfo(nX, nY);
nCount := 0;
if pMapCellInfo <> nil then
begin
if pMapCellInfo^.m_xpObjectList <> nil then
begin
with pMapCellInfo^.m_xpObjectList.LockList do
begin
for I := 0 to COunt - 1 do // Iterate
begin
pOSObject := items[I];
if pOSObject <> nil then
begin
if pOSObject^.btType = OS_MOVINGOBJECT then
begin
pCharObject := TCharObject(pOSObject^.pObject);
if (pCharObject.m_fIsDead = False) and (pCharObject.m_fIsGhost =
False) and (pCharObject.m_fHideMode) then
begin
Inc(nCount);
end;
end;
end;
end; // for
end; // with
pMapCellInfo^.m_xpObjectList.UnlockList;
end;
end;
Result := nCount;
end;
function TMirMap.GetItem(nX, nY: Integer): PMAPITEM_RCD;
var
I: Integer;
pMapCellInfo: PMAPCELLINFO_RCD;
pOSObject: POSOBJECT_RCD;
pCharObject: TCharObject;
begin
pMapCellInfo := GetMapCellInfo(nX, nY);
if pMapCellInfo <> nil then
begin
if pMapCellInfo^.m_xpObjectList <> nil then
begin
with pMapCellInfo^.m_xpObjectList.LockList do
begin
for I := 0 to COunt - 1 do // Iterate
begin
pOSObject := items[I];
if pOSObject <> nil then
begin
if pOSObject^.btType = OS_ITEMOBJECT then
begin
Result := PMAPITEM_RCD(pOSObject^.pObject);
pMapCellInfo^.m_xpObjectList.UnlockList;
Exit;
end;
end;
end; // for
end; // with
pMapCellInfo^.m_xpObjectList.UnlockList;
end;
end;
Result := nil;
end;
function TMirMap.GetDropPosition(nOrgX, nOrgY, nRange: Integer; var nX, nY:
Integer): Boolean;
var
I, j, ti, tj: Integer;
nLoonCnt: Integer;
begin
nLoonCnt := (4 * nRange) * (nRange + 1);
{ for I := 0 to nLoonCnt - 1 do // Iterate
begin
nX := nOrgX + Integer(g_SearchTable[I].X);
nY := nOrgY + Integer(g_SearchTable[I].Y);
if GetItem(nX, nY) = nil then
begin
Result := True;
Exit;
end;
end; // for
}
for I := -nRange to nRange do
for j := -nRange to nRange do
begin
Randomize;
ti := RandomRange(-nRange, nRange);
tj := RandomRange(-nRange, nRange);
nX := nOrgX + tI;
nY := nOrgY + tj;
if GetItem(nX, nY) = nil then
begin
Result := True;
Exit;
end;
end;
nX := nOrgX;
nY := nOrgY;
Result := False;
end;
function TMirMap.GetEvent(nX, nY: Integer): TObject;
var
I: Integer;
pMapCellInfo: PMAPCELLINFO_RCD;
pOSObject: POSOBJECT_RCD;
begin
pMapCellInfo := GetMapCellInfo(nX, nY);
if pMapCellInfo <> nil then
begin
if (Integer(pMapCellInfo^.m_chFlag) and $1) = 0 then
begin
Result := nil;
Exit;
end;
if pMapCellInfo^.m_xpObjectList <> nil then
begin
with pMapCellInfo^.m_xpObjectList.LockList do
begin
for I := 0 to COunt - 1 do // Iterate
begin
pOSObject := items[I];
if pOSObject <> nil then
begin
if pOSObject^.btType = OS_EVENTOBJECT then
begin
Result := TEvent(pOSObject^.pObject);
pMapCellInfo^.m_xpObjectList.UnlockList;
Exit;
end;
end;
end; // for
end; // with
pMapCellInfo^.m_xpObjectList.UnlockList;
end;
end;
Result := nil;
end;
function TMirMap.CanSafeWalk(nX, nY: Integer): Boolean;
var
I: Integer;
pMapCellInfo: PMAPCELLINFO_RCD;
pOSObject: POSOBJECT_RCD;
pEvent: TEvent;
begin
pMapCellInfo := GetMapCellInfo(nX, nY);
if pMapCellInfo <> nil then
begin
if pMapCellInfo^.m_xpObjectList <> nil then
begin
with pMapCellInfo^.m_xpObjectList.LockList do
begin
for I := 0 to COunt - 1 do // Iterate
begin
pOSObject := items[I];
if pOSObject <> nil then
begin
if pOSObject^.btType = OS_EVENTOBJECT then
begin
pEvent := TEvent(pOSObject^.pObject);
if pEvent.m_nDamage > 0 then
begin
Result := False;
pMapCellInfo^.m_xpObjectList.UnlockList;
Exit;
end;
end;
end;
end; // for
end; // with
pMapCellInfo^.m_xpObjectList.UnlockList;
end;
end;
Result := True;
end;
function TMirMap.GetMapCellInfo(nX, nY: Integer): PMAPCELLINFO_RCD;
begin
if ((nX >= 0) and (nX < m_stMapFH.shWidth)) and ((nY >= 0) and (nY <
m_stMapFH.shHeight)) then
begin
Result := @m_pMapCellInfo[nX * m_stMapFH.shHeight + nY];
Exit;
end;
Result := nil;
end;
end.