📄 castle.pas
字号:
unit Castle;
interface
uses
Windows, Classes, SysUtils, IniFiles, Grobal2, ObjBase, ObjMon2, Guild, Math,
Envir,mylist;
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
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_boCanNULL : Boolean;
m_boShowOverMsg: Boolean; //0x42 是否已显示攻城结束信息
m_dwStartCastleWarTick: LongWord; //0x44
m_dwSaveTick: LongWord; //0x48
m_AttackWarList: TMyList; //0x4C
m_AttackGuildList: TMyList; //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_sConfigIndex :Integer;
m_EnvirList: TStringList;
m_nTechLevel: Integer; //科技等级
m_nPower: Integer; //电力量
WarDateIndex: Byte;
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(CastleIndex: Integer);
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(Tariff,ReBate,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: TMyList;
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(Tariff,ReBate,nGold: Integer);
end;
implementation
uses UsrEngn, M2Share, HUtil32, DataModule_Sql;
{ TUserCastle }
constructor TUserCastle.Create(CastleIndex: Integer); //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_sConfigIndex := CastleIndex;
m_sPalaceMap := '0150';
m_sSecretMap := 'D701';
m_MapCastle := nil;
m_DoorStatus := nil;
m_boStartWar := False;
m_boUnderWar := False;
m_boShowOverMsg := False;
m_AttackWarList := TMyList.create;
m_AttackGuildList := TMyList.create;
m_dwSaveTick := 0;
m_nWarRangeX := g_Config.nCastleWarRangeX;
m_nWarRangeY := g_Config.nCastleWarRangeY;
m_EnvirList := TStringList.Create;
WarDateIndex := 0;
m_MainDoor.sName:= 'MainDoor';
m_MainDoor.nX:=672;
m_MainDoor.nY:=330;
m_MainDoor.nHP:=20000;
m_LeftWall.sName:='LeftWall';
m_LeftWall.nX:=624;
m_LeftWall.nY:=278;
m_LeftWall.nHP:=10000;
m_CenterWall.sName:='CenterWall';
m_CenterWall.nX:=627;
m_CenterWall.nY:=278;
m_CenterWall.nHP:=10000;
m_RightWall.sName:='RightWall';
m_RightWall.nX:=634;
m_RightWall.nY:=271;
m_RightWall.nHP:=10000;
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>0 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(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;
if ObjUnit.BaseObject.m_btRaceServer=112 then
Begin
TGuardUnit(ObjUnit.BaseObject).m_nX550 := ObjUnit.nX;
TGuardUnit(ObjUnit.BaseObject).m_nY554 := ObjUnit.nY;
TGuardUnit(ObjUnit.BaseObject).m_nDirection := 3;
End;
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;
//CODE:0048E935
end;
end;
procedure TUserCastle.LoadConfig(); //0048F5BC
var
sFileName, sConfigFile : string;
CastleConf : TIniFile;
i : Integer;
ObjUnit : pTObjUnit;
sMapList, sMAP : string;
Posindex:Integer;
begin
DataModule_mir200[0].CastleLoadConfig(self);
end;
procedure TUserCastle.SaveConfigFile(); //0048EFCC
var
CastleConf : TIniFile;
ObjUnit : pTObjUnit;
sFileName, sConfigFile : string;
sMapList : string;
i : Integer;
sqlStr : String;
begin
DataModule_mir200[0].CastleSaveConfigFile(self);
end;
procedure TUserCastle.LoadAttackSabukWall(); //0048ED60
var
i : Integer;
sFileName, sConfigFile : string;
LoadList : TStringList;
sData : string;
s20, sGuildName : string;
Guild : TGUild;
AttackerInfo : pTAttackerInfo;
D : TDateTime;
begin
DataModule_mir200[0].LoadAttackSabukWall(self);
end;
procedure TUserCastle.SaveAttackSabukWall(); //0048EBD0
var
i : Integer;
SqlStr : String;
AttackerInfo : pTAttackerInfo;
begin
DataModule_mir200[0].SaveAttackSabukWall(self);
end;
procedure TUserCastle.Run; //0048FE4C
{$IF SoftVersion <> VERDEMO}
var
i : Integer;
Year, Month, Day, Hour, Min, Sec, MSec: Word;
wYear, wMonth, wDay : Word;
AttackerInfo : pTAttackerInfo;
s20 : string;
{$IFEND}
resourcestring
sWarStartMsg = '[%s 攻城战已经开始]';
sWarStopTimeMsg = '[%s 攻城战离结束还有%d分钟]';
sExceptionMsg = '[Exception] TUserCastle::Run';
begin
try
if nServerIndex <> g_MapManager.GetMapOfServerIndex(m_sMapName) then
exit;
{$IF SoftVersion <> VERDEMO}
DecodeDate(Now, Year, Month, Day);
DecodeDate(m_IncomeToday, wYear, wMonth, wDay);
if (Year <> wYear) or (Month <> wMonth) or (Day <> wDay) then
begin
m_nTodayIncome := 0;
m_IncomeToday := Now();
m_boStartWar := False;
end;
if not m_boStartWar and (not m_boUnderWar) then
begin
DecodeTime(Time, Hour, Min, Sec, MSec);
if Hour = g_Config.nStartCastlewarTime {20} then
begin
m_boStartWar := True;
;
m_AttackGuildList.Clear;
for i := m_AttackWarList.Count - 1 downto 0 do
begin
AttackerInfo := m_AttackWarList.Items[i];
DecodeDate(AttackerInfo.AttackDate, wYear, wMonth, wDay);
if (Year = wYear) and (Month = wMonth) and (Day = wDay) then
begin
m_boUnderWar := True;
m_boShowOverMsg := False;
m_WarDate := Now();
m_dwStartCastleWarTick := GetTickCount();
m_AttackGuildList.Add(AttackerInfo.Guild);
DisPose(AttackerInfo);
m_AttackWarList.Delete(i);
end;
end;
if m_boUnderWar then
begin
m_AttackGuildList.Add(m_MasterGuild);
StartWallconquestWar();
SaveAttackSabukWall();
UserEngine.SendServerGroupMsg(SS_212, nServerIndex, '');
s20 := format(sWarStartMsg, [m_sName]);
UserEngine.SendBroadCastMsgExt(s20, t_System);
UserEngine.SendServerGroupMsg(SS_204, nServerIndex, s20);
MainOutMessage(s20);
MainDoorControl(True);
end;
end;
end;
for i := Low(m_Guard) to High(m_Guard) do
begin
if (m_Guard[i].BaseObject <> nil) and (m_Guard[i].BaseObject.m_boGhost)
then
begin
m_Guard[i].BaseObject := nil;
end;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -