📄 castle.pas
字号:
unit Castle;
interface
uses
Windows, Classes, SysUtils, IniFiles, Grobal2,SDK, 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 No map found. ( No inner wall map of wall conquest war )',[m_sPalaceMap]));
end;
m_MapSecret:=g_MapManager.FindMap(m_sSecretMap);
if m_MapSecret = nil then begin
MainOutMessage(format('%s - secret map not found !!',[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('[Error] UserCastle.Initialize MainDoor.UnitObj = nil');
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('[Error] UserCastle.Initialize LeftWall.UnitObj = nil');
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('[Error] UserCastle.Initialize CenterWall.UnitObj = nil');
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('[Error] UserCastle.Initialize RightWall.UnitObj = nil');
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('[Error] UserCastle.Initialize Archer -> UnitObj = nil');
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('[Error] UserCastle.Initialize Guard -> UnitObj = nil');
//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('<Critical Error> UserCastle : [Defense]->CastleMap is invalid value (%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;
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);
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);
m_LeftWall.BaseObject:=nil;
m_CenterWall.nX:=CastleConf.ReadInteger('Defense','CenterWallX',627);
m_CenterWall.nY:=CastleConf.ReadInteger('Defense','CenterWallY',278);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -