⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 castle.pas

📁 乐都SQL版传奇全套代码,绝对可编译
💻 PAS
📖 第 1 页 / 共 3 页
字号:
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 + -