📄 castle.pas
字号:
unit Castle;
interface
uses
Windows, Classes, SysUtils, IniFiles, Grobal2, ObjBase, ObjMon2, Guild, Envir;
const
MAXCASTLEARCHER = 12;
MAXCALSTEGUARD = 4;
type
TDefenseUnit = record
nMainDoorX: Integer; //0x00
nMainDoorY: Integer; //0x04
sMainDoorName: string; //0x08
boXXX: Boolean; //0x0C
wMainDoorHP: Word; //0x10
MainDoor: TBaseObject;
LeftWall: TBaseObject;
CenterWall: TBaseObject;
RightWall: TBaseObject;
Archer: TBaseObject;
end;
pTDefenseUnit = ^TDefenseUnit;
TObjUnit = record
nX: Integer; //0x0
nY: Integer; //0x4
sName: string; //0x8
// nStatus :Integer; //0x0C
nStatus: Boolean; //0x0C
nHP: Integer; //0x10
BaseObject: TBaseObject; //0x14
end;
pTObjUnit = ^TObjUnit;
TAttackerInfo = record
AttackDate: TDateTime;
sGuildName: string;
Guild: TGUild;
end;
pTAttackerInfo = ^TAttackerInfo;
TUserCastle = class
m_MapCastle: TEnvirnoment; //0x4 城堡所在地图
m_MapPalace: TEnvirnoment; //0x8 皇宫所在地图
m_MapSecret: TEnvirnoment; //0xC 密道所在地图
m_DoorStatus: pTDoorStatus; //0x10 皇宫门状态
m_sMapName: string; //0x14 城堡所在地图名
m_sName: string; //0x18 城堡名称
m_sOwnGuild: string; //0x1C 所属行会名称
m_MasterGuild: TGUild; //0x20 所属行会
m_sHomeMap: string; //0x24 行会回城点地图
m_nHomeX: Integer; //0x28 行会回城点X
m_nHomeY: Integer; //0x2C 行会回城点Y
m_ChangeDate: TDateTime; //0x30
m_WarDate: TDateTime; //0x38
m_boStartWar: Boolean; //0x40 是否开始攻城
m_boUnderWar: Boolean; //0x41 是否正在攻城
m_boShowOverMsg: Boolean; //0x42 是否已显示攻城结束信息
m_dwStartCastleWarTick: LongWord; //0x44
m_dwSaveTick: LongWord; //0x48
m_AttackWarList: TList; //0x4C
m_AttackGuildList: TList; //0x50
m_MainDoor: TObjUnit; //0x54
m_LeftWall: TObjUnit; //0x6C
m_CenterWall: TObjUnit; //0x84
m_RightWall: TObjUnit; //0x9C
m_Guard: array[0..MAXCALSTEGUARD - 1] of TObjUnit; //0xB4
m_Archer: array[0..MAXCASTLEARCHER - 1] of TObjUnit; //0x114 0x264
m_IncomeToday: TDateTime; //0x238
m_nTotalGold: Integer; //0x240
m_nTodayIncome: Integer; //0x244
m_nWarRangeX: Integer; //攻城区域范围X
m_nWarRangeY: Integer; //攻城区域范围Y
m_boStatus: Boolean;
m_sPalaceMap: string; //皇宫所在地图
m_sSecretMap: string; //密道所在地图
m_nPalaceDoorX: Integer; //皇宫座标X
m_nPalaceDoorY: Integer; //皇宫座标Y
m_sConfigDir: string;
m_EnvirList: TStringList;
m_nTechLevel: Integer; //科技等级
m_nPower: Integer; //电力量
private
procedure LoadAttackSabukWall();
procedure SaveConfigFile();
procedure LoadConfig();
procedure SaveAttackSabukWall();
function InAttackerList(Guild: TGUild): Boolean;
procedure SetTechLevel(nLevel: Integer);
procedure SetPower(nPower: Integer);
function m_nChiefItemCount: Integer;
public
constructor Create(sCastleDir: string);
destructor Destroy; override;
procedure Initialize();
procedure Run();
procedure Save();
function InCastleWarArea(Envir: TEnvirnoment; nX, nY: Integer): Boolean;
function IsMember(Cert: TBaseObject): Boolean;
function IsMasterGuild(Guild: TGUild): Boolean;
function IsAttackGuild(Guild: TGUild): Boolean;
function IsAttackAllyGuild(Guild: TGUild): Boolean;
function IsDefenseGuild(Guild: TGUild): Boolean;
function IsDefenseAllyGuild(Guild: TGUild): Boolean;
function CanGetCastle(Guild: TGUild): Boolean;
procedure GetCastle(Guild: TGUild);
procedure StartWallconquestWar;
procedure StopWallconquestWar();
function InPalaceGuildCount(): Integer;
function GetHomeX(): Integer;
function GetHomeY(): Integer;
function GetMapName(): string;
function AddAttackerInfo(Guild: TGUild): Boolean;
function CheckInPalace(nX, nY: Integer; Cert: TBaseObject): Boolean;
function GetWarDate(): string;
function GetAttackWarList(): string;
procedure IncRateGold(nGold: Integer);
function WithDrawalGolds(PlayObject: TPlayObject; nGold: Integer): Integer;
function ReceiptGolds(PlayObject: TPlayObject; nGold: Integer): Integer;
procedure MainDoorControl(boClose: Boolean);
function RepairDoor(): Boolean;
function RepairWall(nWallIndex: Integer): Boolean;
property nTechLevel: Integer read m_nTechLevel write SetTechLevel;
property nPower: Integer read m_nPower write SetPower;
end;
TCastleManager = class
private
CriticalSection: TRTLCriticalSection;
protected
public
m_CastleList: TList;
constructor Create();
destructor Destroy; override;
procedure LoadCastleList();
procedure SaveCastleList();
procedure Initialize();
procedure Lock;
procedure UnLock;
procedure Run();
procedure Save();
function Find(sCASTLENAME: string): TUserCastle;
function GetCastle(nIndex: Integer): TUserCastle;
function InCastleWarArea(BaseObject: TBaseObject): TUserCastle; overload;
function InCastleWarArea(Envir: TEnvirnoment; nX, nY: Integer): TUserCastle; overload;
function IsCastleMember(BaseObject: TBaseObject): TUserCastle;
function IsCastlePalaceEnvir(Envir: TEnvirnoment): TUserCastle;
function IsCastleEnvir(Envir: TEnvirnoment): TUserCastle;
procedure GetCastleGoldInfo(List: TStringList);
procedure GetCastleNameList(List: TStringList);
procedure IncRateGold(nGold: Integer);
end;
implementation
uses UsrEngn, M2Share, HUtil32;
{ TUserCastle }
constructor TUserCastle.Create(sCastleDir: string); //0048E438
begin
m_MasterGuild := nil;
m_sHomeMap := g_Config.sCastleHomeMap {'3'};
m_nHomeX := g_Config.nCastleHomeX {644};
m_nHomeY := g_Config.nCastleHomeY {290};
m_sName := g_Config.sCASTLENAME {'沙巴克'};
m_sConfigDir := sCastleDir;
m_sPalaceMap := '0150';
m_sSecretMap := 'D701';
m_MapCastle := nil;
m_DoorStatus := nil;
m_boStartWar := False;
m_boUnderWar := False;
m_boShowOverMsg := False;
m_AttackWarList := TList.Create;
m_AttackGuildList := TList.Create;
m_dwSaveTick := 0;
m_nWarRangeX := g_Config.nCastleWarRangeX;
m_nWarRangeY := g_Config.nCastleWarRangeY;
m_EnvirList := TStringList.Create;
end;
destructor TUserCastle.Destroy; //0048E51C
var
I: Integer;
begin
for I := 0 to m_AttackWarList.Count - 1 do begin
Dispose(pTAttackerInfo(m_AttackWarList.Items[I]));
end;
m_AttackWarList.Free;
m_AttackGuildList.Free;
m_EnvirList.Free;
inherited;
end;
procedure TUserCastle.Initialize; //0048E564
var
I: Integer;
ObjUnit: pTObjUnit;
Door: pTDoorInfo;
begin
LoadConfig();
LoadAttackSabukWall();
if g_MapManager.GetMapOfServerIndex(m_sMapName) = nServerIndex then begin
//m_MapPalace:=EnvirList.FindMap('0150');
m_MapPalace := g_MapManager.FindMap(m_sPalaceMap);
if m_MapPalace = nil then begin
MainOutMessage(Format('皇宫地图%s没找到!!!', [m_sPalaceMap]));
end;
m_MapSecret := g_MapManager.FindMap(m_sSecretMap);
if m_MapSecret = nil then begin
MainOutMessage(Format('密道地图%s没找到!!!', [m_sSecretMap]));
//ShowMessage('0150 没有找到地图...');
end;
m_MapCastle := g_MapManager.FindMap(m_sMapName);
if m_MapCastle <> nil then begin
m_MainDoor.BaseObject := UserEngine.RegenMonsterByName(m_sMapName, m_MainDoor.nX, m_MainDoor.nY, m_MainDoor.sName);
if m_MainDoor.BaseObject <> nil then begin
m_MainDoor.BaseObject.m_WAbil.HP := m_MainDoor.nHP;
m_MainDoor.BaseObject.m_Castle := Self;
// if MainDoor.nStatus <> 0 then begin
if m_MainDoor.nStatus then begin
TCastleDoor(m_MainDoor.BaseObject).Open;
end;
// MainOutMessage(format('Name:%s Map:%s X:%d Y:%d HP:%d',[MainDoor.BaseObject.m_sCharName,MainDoor.BaseObject.m_sMapName,MainDoor.BaseObject.m_nCurrX,MainDoor.BaseObject.m_nCurrY,MainDoor.BaseObject.m_Wabil.HP]));
end else begin
MainOutMessage('[错误信息] 城堡初始化城门失败,检查怪物数据库里有没城门的设置: ' + m_MainDoor.sName);
end;
m_LeftWall.BaseObject := UserEngine.RegenMonsterByName(m_sMapName, m_LeftWall.nX, m_LeftWall.nY, m_LeftWall.sName);
if m_LeftWall.BaseObject <> nil then begin
m_LeftWall.BaseObject.m_WAbil.HP := m_LeftWall.nHP;
m_LeftWall.BaseObject.m_Castle := Self;
//MainOutMessage('m_LeftWall.BaseObject.m_WAbil.HP '+IntToStr(m_LeftWall.BaseObject.m_WAbil.HP));
// MainOutMessage(format('Name:%s Map:%s X:%d Y:%d HP:%d',[LeftWall.BaseObject.m_sCharName,LeftWall.BaseObject.m_sMapName,LeftWall.BaseObject.m_nCurrX,LeftWall.BaseObject.m_nCurrY,LeftWall.BaseObject.m_Wabil.HP]));
end else begin
MainOutMessage('[错误信息] 城堡初始化左城墙失败,检查怪物数据库里有没左城墙的设置: ' + m_LeftWall.sName);
end;
m_CenterWall.BaseObject := UserEngine.RegenMonsterByName(m_sMapName, m_CenterWall.nX, m_CenterWall.nY, m_CenterWall.sName);
if m_CenterWall.BaseObject <> nil then begin
m_CenterWall.BaseObject.m_WAbil.HP := m_CenterWall.nHP;
m_CenterWall.BaseObject.m_Castle := Self;
// MainOutMessage(format('Name:%s Map:%s X:%d Y:%d HP:%d',[CenterWall.BaseObject.m_sCharName,CenterWall.BaseObject.m_sMapName,CenterWall.BaseObject.m_nCurrX,CenterWall.BaseObject.m_nCurrY,CenterWall.BaseObject.m_Wabil.HP]));
end else begin
MainOutMessage('[错误信息] 城堡初始化中城墙失败,检查怪物数据库里有没中城墙的设置: ' + m_CenterWall.sName);
end;
m_RightWall.BaseObject := UserEngine.RegenMonsterByName(m_sMapName, m_RightWall.nX, m_RightWall.nY, m_RightWall.sName);
if m_RightWall.BaseObject <> nil then begin
m_RightWall.BaseObject.m_WAbil.HP := m_RightWall.nHP;
m_RightWall.BaseObject.m_Castle := Self;
// MainOutMessage(format('Name:%s Map:%s X:%d Y:%d HP:%d',[RightWall.BaseObject.m_sCharName,RightWall.BaseObject.m_sMapName,RightWall.BaseObject.m_nCurrX,RightWall.BaseObject.m_nCurrY,RightWall.BaseObject.m_Wabil.HP]));
end else begin
MainOutMessage('[错误信息] 城堡初始化右城墙失败,检查怪物数据库里有没右城墙的设置: ' + m_RightWall.sName);
end;
for I := Low(m_Archer) to High(m_Archer) do begin
ObjUnit := @m_Archer[I];
if ObjUnit.nHP <= 0 then Continue;
ObjUnit.BaseObject := UserEngine.RegenMonsterByName(m_sMapName, ObjUnit.nX, ObjUnit.nY, ObjUnit.sName);
if ObjUnit.BaseObject <> nil then begin
ObjUnit.BaseObject.m_WAbil.HP := m_Archer[I].nHP;
ObjUnit.BaseObject.m_Castle := Self;
TGuardUnit(ObjUnit.BaseObject).m_nX550 := ObjUnit.nX;
TGuardUnit(ObjUnit.BaseObject).m_nY554 := ObjUnit.nY;
TGuardUnit(ObjUnit.BaseObject).m_nDirection := 3;
end else begin
//MainOutMessage('[错误信息] UserCastle.Initialize Archer -> UnitObj = nil');
MainOutMessage('[错误信息] 城堡初始化弓箭手失败,检查怪物数据库里有没弓箭手的设置: ' + ObjUnit.sName);
end;
end;
for I := Low(m_Guard) to High(m_Guard) do begin
ObjUnit := @m_Guard[I];
if ObjUnit.nHP <= 0 then Continue;
ObjUnit.BaseObject := UserEngine.RegenMonsterByName(m_sMapName, ObjUnit.nX, ObjUnit.nY, ObjUnit.sName);
if ObjUnit.BaseObject <> nil then begin
ObjUnit.BaseObject.m_WAbil.HP := m_Guard[I].nHP;
end else begin
MainOutMessage('[错误信息] 城堡初始化守卫失败(检查怪物数据库里有没守卫怪物)');
//MainOutMessage('[错误信息] UserCastle.Initialize Guard -> UnitObj = nil');
end;
end;
for I := 0 to m_MapCastle.m_DoorList.Count - 1 do begin
Door := m_MapCastle.m_DoorList.Items[I];
if (abs(Door.nX - m_nPalaceDoorX {631}) <= 3) and (abs(Door.nY - m_nPalaceDoorY {274}) <= 3) then begin
m_DoorStatus := Door.Status;
end;
end;
end else begin
MainOutMessage(Format('[错误信息] 城堡所在地图不存在(检查地图配置文件里是否有地图%s的设置)', [m_sMapName]));
//MainOutMessage('[错误信息] TUserCastle.Initialize CastleMap -> nil');
end;
end;
end;
procedure TUserCastle.LoadConfig();
var
sFileName, sConfigFile: string;
CastleConf: TIniFile;
I: Integer;
ObjUnit: pTObjUnit;
sMapList, sMAP: string;
begin
if not DirectoryExists(g_Config.sCastleDir + m_sConfigDir) then begin
CreateDir(g_Config.sCastleDir + m_sConfigDir);
end;
sConfigFile := 'SabukW.txt';
sFileName := g_Config.sCastleDir + m_sConfigDir + '\' + sConfigFile;
CastleConf := TIniFile.Create(sFileName);
if CastleConf <> nil then begin
m_sName := CastleConf.ReadString('Setup', 'CastleName', m_sName);
m_sOwnGuild := CastleConf.ReadString('Setup', 'OwnGuild', '');
m_ChangeDate := CastleConf.ReadDateTime('Setup', 'ChangeDate', Now);
m_WarDate := CastleConf.ReadDateTime('Setup', 'WarDate', Now);
m_IncomeToday := CastleConf.ReadDateTime('Setup', 'IncomeToday', Now);
m_nTotalGold := CastleConf.ReadInteger('Setup', 'TotalGold', 0);
m_nTodayIncome := CastleConf.ReadInteger('Setup', 'TodayIncome', 0);
sMapList := CastleConf.ReadString('Defense', 'CastleMapList', '');
if sMapList <> '' then begin
while (sMapList <> '') do begin
sMapList := GetValidStr3(sMapList, sMAP, [',']);
if sMAP = '' then Break;
m_EnvirList.Add(sMAP);
end;
end;
for I := 0 to m_EnvirList.Count - 1 do begin
m_EnvirList.Objects[I] := g_MapManager.FindMap(m_EnvirList.Strings[I]);
end;
m_sMapName := CastleConf.ReadString('Defense', 'CastleMap', '3');
m_sHomeMap := CastleConf.ReadString('Defense', 'CastleHomeMap', m_sHomeMap);
m_nHomeX := CastleConf.ReadInteger('Defense', 'CastleHomeX', m_nHomeX);
m_nHomeY := CastleConf.ReadInteger('Defense', 'CastleHomeY', m_nHomeY);
m_nWarRangeX := CastleConf.ReadInteger('Defense', 'CastleWarRangeX', m_nWarRangeX);
m_nWarRangeY := CastleConf.ReadInteger('Defense', 'CastleWarRangeY', m_nWarRangeY);
m_sPalaceMap := CastleConf.ReadString('Defense', 'CastlePlaceMap', m_sPalaceMap);
m_sSecretMap := CastleConf.ReadString('Defense', 'CastleSecretMap', m_sSecretMap);
m_nPalaceDoorX := CastleConf.ReadInteger('Defense', 'CastlePalaceDoorX', 631);
m_nPalaceDoorY := CastleConf.ReadInteger('Defense', 'CastlePalaceDoorY', 274);
m_MainDoor.nX := CastleConf.ReadInteger('Defense', 'MainDoorX', 672);
m_MainDoor.nY := CastleConf.ReadInteger('Defense', 'MainDoorY', 330);
m_MainDoor.sName := CastleConf.ReadString('Defense', 'MainDoorName', 'MainDoor');
m_MainDoor.nStatus := CastleConf.ReadBool('Defense', 'MainDoorOpen', True);
m_MainDoor.nHP := CastleConf.ReadInteger('Defense', 'MainDoorHP', 2000);
if m_MainDoor.nHP <= 0 then m_MainDoor.nHP := 2000;
m_MainDoor.BaseObject := nil;
m_LeftWall.nX := CastleConf.ReadInteger('Defense', 'LeftWallX', 624);
m_LeftWall.nY := CastleConf.ReadInteger('Defense', 'LeftWallY', 278);
m_LeftWall.sName := CastleConf.ReadString('Defense', 'LeftWallName', 'LeftWall');
m_LeftWall.nHP := CastleConf.ReadInteger('Defense', 'LeftWallHP', 2000);
if m_LeftWall.nHP <= 0 then m_LeftWall.nHP := 2000;
m_LeftWall.BaseObject := nil;
m_CenterWall.nX := CastleConf.ReadInteger('Defense', 'CenterWallX', 627);
m_CenterWall.nY := CastleConf.ReadInteger('Defense', 'CenterWallY', 278);
m_CenterWall.sName := CastleConf.ReadString('Defense', 'CenterWallName', 'CenterWall');
m_CenterWall.nHP := CastleConf.ReadInteger('Defense', 'CenterWallHP', 2000);
if m_CenterWall.nHP <= 0 then m_CenterWall.nHP := 2000;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -