unit kys_main;

{
 All Heros in Kam Yung's Stories - The Replicated Edition
 
 Created by S.weyl in 2008 May.
 No Copyright (C) reserved.
 
 You can build it by Delphi with JEDI-SDL support.
 
 This resouce code file which is not perfect so far,
 can be modified and rebuilt freely,
 or translate it to another programming language.
 But please keep this section when you want to spread a new vision. Thanks.
 Note: it must not be a good idea to use this as a pascal paradigm.

}

{
 任何人获得这份代码之后, 均可以自由增删功能, 重新
 编译, 或译为其他语言. 但请保留本段文字.
}

interface

uses
  SysUtils,
  Windows,
  math,
  Dialogs,
  SDL,
  SDL_TTF,
  SDL_mixer,
  SDL_image,
  iniFiles,
  lua;

type

  TPosition = record
    x, y: integer;
  end;

  TRect = record
    x, y, w, h: integer;
  end;

  TItemList = record
    Number, Amount: Smallint;
  end;

  TCallType = (Element, Address);

  //以下所有类型均有两种引用方式：按照别名引用；按照短整数数组引用

  TRole = record
    case TCallType of
      Element:
      (ListNum, HeadNum, IncLife, UnUse: Smallint;
        Name, Nick: array[0..9] of char;
        Sexual, Level: Smallint;
        Exp: Uint16;
        CurrentHP, MaxHP, Hurt, Poision, PhyPower: Smallint;
        ExpForItem: Uint16;
        Equip: array[0..1] of Smallint;
        AmiFrameNum, AmiDelay, SoundDealy: array[0..4] of smallint;
        MPType, CurrentMP, MaxMP: Smallint;
        Attack, Speed, Defence, Medcine, UsePoi, MedPoi, DefPoi, Fist, Sword, Knife, Unusual, HidWeapon: Smallint;
        Knowledge, Ethics, AttPoi, AttTwice, Repute, Aptitude, PracticeBook: Smallint;
        ExpForBook: Uint16;
        Magic, MagLevel: array[0..9] of smallint;
        TakingItem, TakingItemAmount: array[0..3] of smallint);
      Address:
      (Data: array[0..90] of Smallint);
  end;

  TItem = record
    case TCallType of
      Element:
      (ListNum: Smallint;
        Name, Name1: array[0..19] of char;
        Introduction: array[0..29] of char;
        Magic, AmiNum, User, EquipType, ShowIntro, ItemType, UnKnow5, UnKnow6, UnKnow7: Smallint;
        AddCurrentHP, AddMaxHP, AddPoi, AddPhyPower, ChangeMPType, AddCurrentMP, AddMaxMP: Smallint;
        AddAttack, AddSpeed, AddDefence, AddMedcine, AddUsePoi, AddMedPoi, AddDefPoi: Smallint;
        AddFist, AddSword, AddKnife, AddUnusual, AddHidWeapon, AddKnowledge, AddEthics, AddAttTwice, AddAttPoi: Smallint;
        OnlyPracRole, NeedMPType, NeedMP, NeedAttack, NeedSpeed, NeedUsePoi, NeedMedcine, NeedMedPoi: Smallint;
        NeedFist, NeedSword, NeedKnife, NeedUnusual, NeedHidWeapon, NeedAptitude: Smallint;
        NeedExp, NeedExpForItem, NeedMaterial: Smallint;
        GetItem, NeedMatAmount: array[0..4] of Smallint);
      Address:
      (Data: array[0..94] of Smallint);
  end;

  TScence = record
    case TCallType of
      Element:
      (ListNum: Smallint;
        Name: array[0..9] of char;
        ExitMusic, EntranceMusic: Smallint;
        JumpScence, EnCondition: Smallint;
        MainEntranceY1, MainEntranceX1, MainEntranceY2, MainEntranceX2: Smallint;
        EntranceY, EntranceX: Smallint;
        ExitY, ExitX: array[0..2] of Smallint;
        JumpY1, JumpX1, JumpY2, JumpX2: Smallint);
      Address:
      (Data: array[0..25] of Smallint);
  end;

  TMagic = record
    case TCallType of
      Element:
      (ListNum: Smallint;
        Name: array[0..9] of char;
        UnKnow: array[0..4] of Smallint;
        SoundNum, MagicType, AmiNum, HurtType, AttAreaType, NeedMP, Poision: Smallint;
        Attack, MoveDistance, AttDistance, AddMP, HurtMP: array[0..9] of Smallint);
      Address:
      (Data: array[0..67] of Smallint);
  end;

  TShop = record
    case TCallType of
      Element:
      (Item, Amount, Price: array[0..4] of Smallint);
      Address:
      (Data: array[0..14] of Smallint);
  end;

  TBattleRole = record
    case TCallType of
      Element:
      (rnum, Team, Y, X, Face, Dead, Step, Acted: Smallint;
        Pic, ShowNumber, UnUse1, UnUse2, UnUse3, ExpGot, Auto: Smallint);
      Address:
      (Data: array[0..14] of Smallint);
  end;

  //程序重要子程
procedure Run;
procedure Quit;

//游戏开始画面, 行走等
procedure Start;
procedure StartAmi;
procedure ReadFiles;
procedure InitialRole;
procedure LoadR(num: integer);
procedure SaveR(num: integer);
function WaitAnyKey: integer;
procedure Walk;
function CanWalk(x, y: integer): boolean;
procedure CheckEntrance;
function InScence(open: integer): integer;
procedure ShowScenceName(snum: integer);
function CanWalkInScence(x, y: integer): boolean;
procedure CheckEvent3;

//选单子程
function CommonMenu(x, y, w, max: integer): integer;
procedure ShowCommonMenu(x, y, w, max, menu: integer);
function CommonScrollMenu(x, y, w, max, maxshow: integer): integer;
procedure ShowCommonScrollMenu(x, y, w, max, maxshow, menu, menutop: integer);
function CommonMenu2(x, y, w: integer): integer;
procedure ShowCommonMenu2(x, y, w, menu: integer);
function SelectOneTeamMember(x, y: integer; str: string; list1, list2: integer): integer;
procedure MenuEsc;
procedure ShowMenu(menu: integer);
procedure MenuMedcine;
procedure MenuMedPoision;
function MenuItem: boolean;
function ReadItemList(ItemType: integer): integer;
procedure ShowMenuItem(row, col, x, y, atlu: integer);
procedure DrawItemFrame(x, y: integer);
procedure UseItem(inum: integer);
function CanEquip(rnum, inum: integer): boolean;
procedure MenuStatus;
procedure ShowStatus(rnum: integer);
procedure MenuLeave;
procedure MenuSystem;
procedure ShowMenuSystem(menu: integer);
procedure MenuLoad;
procedure MenuLoadAtBeginning;
procedure MenuSave;
procedure MenuQuit;

//医疗, 解毒, 使用物品的效果等
procedure EffectMedcine(role1, role2: integer);
procedure EffectMedPoision(role1, role2: integer);
procedure EatOneItem(rnum, inum: integer);

//事件系统
procedure CallEvent(num: integer);

var

  CHINESE_FONT: PAnsiChar = 'resource\kaiu.ttf';
  CHINESE_FONT_SIZE: integer = 20;
  ENGLISH_FONT: PAnsiChar = 'resource\consola.ttf';
  ENGLISH_FONT_SIZE: integer = 18;

  CENTER_X: integer = 320;
  CENTER_Y: integer = 220;

  //以下为常数表, 其中多数可以由ini文件改变

  ITEM_BEGIN_PIC: integer = 3501; //物品起始图片
  BEGIN_EVENT: integer = 691; //初始事件
  BEGIN_SCENCE: integer = 70; //初始场景
  BEGIN_Sx: integer = 20; //初始坐标(程序中的x, y与游戏中是相反的, 这是早期的遗留问题)
  BEGIN_Sy: integer = 19; //初始坐标
  SOFTSTAR_BEGIN_TALK: integer = 2547; //软体娃娃对话的开始编号
  SOFTSTAR_NUM_TALK: integer = 18; //软体娃娃的对话数量
  MAX_PHYSICAL_POWER: integer = 100; //最大体力
  MONEY_ID: integer = 174; //银两的物品代码
  COMPASS_ID: integer = 182; //罗盘的物品代码
  BEGIN_LEAVE_EVENT: integer = 950; //起始离队事件
  BEGIN_BATTLE_ROLE_PIC: integer = 2553; //人物起始战斗贴图
  MAX_LEVEL: integer = 30; //最大等级
  MAX_WEAPON_MATCH: integer = 7; //'武功武器配合'组合的数量
  MIN_KNOWLEDGE: integer = 80; //最低有效武学常识
  MAX_ITEM_AMOUNT: integer = 200; //最大物品数量
  MAX_HP: integer = 999; //最大生命
  MAX_MP: integer = 999; //最大内功

  MaxProList: array[43..58] of integer = (100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 1);
  //最大攻击值~最大左右互博值

  LIFE_HURT: integer = 10; //伤害值比例

  //以下3个常数实际并未使用, 不能由ini文件指定
  NOVEL_BOOK: integer = 144; //天书起始编码(因偷懒并未使用)
  MAX_HEAD_NUM: integer = 189; //有专有头像的最大人物编号, 仅用于对话指令
  BEGIN_WALKPIC: integer = 2500; //起始的行走贴图(并未使用)

  MPic, SPic, WPic, EPic: array[0..5000000] of byte;
  MIdx, SIdx, WIdx, EIdx: array[0..10000] of integer;
  FPic: array[0..1000000] of byte;
  FIdx: array[0..300] of integer;
  HPic: array[0..2000000] of byte;
  HIdx: array[0..500] of integer;
  //以上为贴图的内容及索引
  Earth, Surface, Building, BuildX, BuildY, Entrance: array[0..479, 0..479] of smallint;
  //主地图数据
  ACol: array[0..768] of byte;
  //默认调色板数据
  InShip, Useless1, Mx, My, Sx, Sy, MFace, ShipX, ShipY, ShipX1, ShipY1, ShipFace: Smallint;
  TeamList: array[0..5] of Smallint;
  RItemList: array of TItemList;

  MStep, Still: integer;
  //主地图坐标, 方向, 步数, 是否处于静止
  Cx, Cy, SFace, SStep: integer;
  //场景内坐标, 场景中心点, 方向, 步数
  CurScence, CurEvent, CurItem, CurrentBattle, Where: integer;
  //当前场景, 事件(在场景中的事件号), 使用物品, 战斗
  //where: 0-主地图, 1-场景, 2-战场, 3-开头画面
  SaveNum: integer;
  //存档号, 未使用
  RRole: array[0..600] of TRole;
  RItem: array[0..500] of TItem;
  RScence: array[0..200] of TScence;
  RMagic: array[0..200] of TMagic;
  RShop: array[0..10] of TShop;
  //R文件数据, 均远大于原有容量

  ItemList: array[0..500] of smallint;

  SData: array[0..400, 0..5, 0..63, 0..63] of smallint;
  DData: array[0..400, 0..199, 0..10] of smallint;
  //S, D文件数据
  //Scence1, SData[CurScence, 1, , Scence3, Scence4, Scence5, Scence6, Scence7, Scence8: array[0..63, 0..63] of smallint;
  //当前场景数据
  //0-地面, 1-建筑, 2-物品, 3-事件, 4-建筑高度, 5-物品高度
  ScenceImg: array[0..2303, 0..1151] of Uint32;
  //场景的图形映像. 实时重画场景效率较低, 故首先生成映像, 需要时载入
  //ScenceD: array[0..199, 0..10] of smallint;
  //当前场景事件
  BFieldImg: array[0..2303, 0..1151] of Uint32;
  //战场图形映像
  BField: array[0..7, 0..63, 0..63] of smallint;
  //战场数据
  //0-地面, 1-建筑, 2-人物, 3-可否被选中, 4-攻击范围, 5, 6 ,7-未使用
  WarSta: array[0..$5D] of smallint;
  //战场数据, 即war.sta文件的映像
  BRole: array[0..99] of TBattleRole;
  //战场人物属性
  //0-人物序号, 1-敌我, 2, 3-坐标, 4-面对方向, 5-是否仍在战场, 6-可移动步数, 7-是否行动完毕,
  //8-贴图(未使用), 9-头上显示数字, 10, 11, 12-未使用, 13-已获得经验, 14-是否自动战斗
  BRoleAmount: integer;
  //战场人物总数
  Bx, By, Ax, Ay: integer;
  //当前人物坐标, 选择目标的坐标
  Bstatus: integer;
  //战斗状态, 0-继续, 1-胜利, 2-失败

  LeaveList: array[0..99] of smallint;
  EffectList: array[0..199] of smallint;
  LevelUpList: array[0..99] of smallint;
  MatchList: array[0..99, 0..2] of smallint;
  //各类列表, 前四个从文件读入

  fullscreen: integer;
  //是否全屏

  screen: PSDL_Surface;
  //主画面
  event: TSDL_Event;
  //事件
  Font, EngFont: PTTF_Font;
  TextColor: TSDL_Color;
  text: PSDL_Surface;
  //字体

  Music: array[0..23] of PMix_music;
  ESound: array[0..52] of PMix_Chunk;
  ASound: array[0..23] of PMix_Chunk;
  //声音
  ExitScenceMusicNum: integer;
  //离开场景的音乐
  MusicName: string;

  MenuString, MenuEngString: array of widestring;
  //选单所使用的字符串

  x50: array[-$8000..$7FFF] of smallint;
  //扩充指令50所使用的变量

  //ScComp: TPSPascalCompiler;
  //ScExec: TPSExec;
  lua_script: Plua_state;

implementation

uses kys_event, kys_battle, kys_engine, kys_script;

//初始化字体, 音效, 视频, 启动游戏

procedure Run;
begin
  //初始化字体
  TTF_Init();
  font := TTF_OpenFont(CHINESE_FONT, CHINESE_FONT_SIZE);
  engfont := TTF_OpenFont(ENGLISH_FONT, ENGLISH_FONT_SIZE);
  if font = nil then
  begin
    MessageBox(0, PChar(Format('Error:%s!', [SDL_GetError])), 'Error', MB_OK or MB_ICONHAND);
    exit;
  end;

  //初始化视频系统
  Randomize;
  if (SDL_Init(SDL_INIT_VIDEO) < 0) then
  begin
    MessageBox(0, PChar(Format('Couldn''t initialize SDL : %s', [SDL_GetError])), 'Error', MB_OK or MB_ICONHAND);
    SDL_Quit;
    exit;
  end;

  //初始化音频系统
  SDL_Init(SDL_INIT_AUDIO);
  Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 4096);
  SDL_WM_SetIcon(IMG_Load('resource\icon.png'), 0);
  screen := SDL_SetVideoMode(CENTER_X * 2, CENTER_Y * 2, 32, SDL_SWSURFACE {or SDL_DOUBLEBUF {or SDL_FULLSCREEN});

  if (screen = nil) then
  begin
    MessageBox(0, PChar(Format('Couldn''t set 640x480x8 video mode : %s', [SDL_GetError])), 'Error', MB_OK or MB_ICONHAND);
    SDL_Quit;
    halt(1);
  end;

  SDL_WM_SetCaption('KYS - Wider Rivers And Deeper Lakes', 's.weyl');

  InitialScript;
  InitialMusic;

  Start;

  DestroyScript;
  TTF_CloseFont(font);
  TTF_CloseFont(engfont);
  TTF_Quit;
  SDL_Quit;
  halt(1);
  exit;

end;

//关闭所有已打开的资源, 退出

procedure Quit;
begin
  DestroyScript;
  TTF_CloseFont(font);
  TTF_CloseFont(engfont);
  TTF_Quit;
  SDL_Quit;
  halt(1);
  exit;

end;

//Main game.
//显示开头画面

procedure Start;
var
  menu, menup, i, col, i1, i2, x, y: integer;
begin

  ReadFiles;

  for i1 := 0 to 479 do
    for i2 := 0 to 479 do
      Entrance[i1, i2] := -1;

  display_img('resource\open.png', 0, 0);

  SDL_EnableKeyRepeat(0, 10);
  MStep := 1;

  fullscreen := 0;

  where := 3;
  menu := 0;
  Setlength(RItemlist, MAX_ITEM_AMOUNT);
  for i := 0 to MAX_ITEM_AMOUNT - 1 do
  begin
    RItemlist[i].Number := -1;
    RItemlist[i].Amount := 0;
  end;

  x := 287;
  y := 270;
  //drawrectanglewithoutframe(270, 150, 100, 70, 0, 20);
  drawtitlepic(0, x, y);
  drawtitlepic(menu + 1, x, y + menu * 20);
  sdl_updaterect(screen, 0, 0, screen.w, screen.h);
  PlayMp3(1, -1);

  //事件等待
  while (SDL_WaitEvent(@event) >= 0) do
  begin
    case event.type_ of
      //关闭窗口事件
      SDL_QUITEV:
        if messagedlg('Are you sure to quit?', mtConfirmation, [mbOk, mbCancel], 0) = idOK then
          Quit;
      //键盘事件
      SDL_KEYUP:
        begin
          //如选择第2项, 则退出(所有编号从0开始)
          if ((event.key.keysym.sym = sdlk_return) or (event.key.keysym.sym = sdlk_space)) and (menu = 2) then
          begin
            break;
          end;
          //选择第0项, 重新开始游戏
          if ((event.key.keysym.sym = sdlk_return) or (event.key.keysym.sym = sdlk_space)) and (menu = 0) then
          begin
            InitialRole;
            CurScence := BEGIN_SCENCE;
            Inscence(1);
            Sdl_UpdateRect(screen, 0, 0, screen.w, screen.h);
            walk;
            menu := 1;
            drawtitlepic(0, x, y);
            drawtitlepic(menu + 1, x, y + menu * 20);
          end;
          //选择第一项, 读入进度
          if ((event.key.keysym.sym = sdlk_return) or (event.key.keysym.sym = sdlk_space)) and (menu = 1) then
          begin
            //LoadR(1);
            menuloadAtBeginning;
            redraw;
            Sdl_UpdateRect(screen, 0, 0, screen.w, screen.h);
            CurEvent := -1; //when CurEvent=-1, Draw scence by Sx, Sy. Or by Cx, Cy.
            Walk;
            menu := 1;
            drawtitlepic(0, x, y);
            drawtitlepic(menu + 1, x, y + menu * 20);
            SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
          end;
          //按下方向键上
          if event.key.keysym.sym = sdlk_up then
          begin
            menu := menu - 1;
            if menu < 0 then
              menu := 2;
            drawtitlepic(0, x, y);
            drawtitlepic(menu + 1, x, y + menu * 20);
            SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
          end;
          //按下方向键下
          if event.key.keysym.sym = sdlk_down then
          begin
            menu := menu + 1;
            if menu > 2 then
              menu := 0;
            drawtitlepic(0, x, y);
            drawtitlepic(menu + 1, x, y + menu * 20);
            SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
          end;
        end;
      //按下鼠标(UP表示抬起按键才执行)
      SDL_MOUSEBUTTONUP:
        begin
          if (event.button.button = sdl_button_left) then
          begin
            case menu of
              2:
                break;
              1:
                begin
                  menuloadAtBeginning;
                  redraw;
                  Sdl_UpdateRect(screen, 0, 0, screen.w, screen.h);
                  CurEvent := -1; //when CurEvent=-1, Draw scence by Sx, Sy. Or by Cx, Cy.
                  Walk;
                  menu := 1;
                  drawtitlepic(0, x, y);
                  drawtitlepic(menu + 1, x, y + menu * 20);
                  SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
                end;
              0:
                begin
                  InitialRole;
                  CurScence := BEGIN_SCENCE;
                  CurEvent := -1;
                  Inscence(1);
                  Sdl_UpdateRect(screen, 0, 0, screen.w, screen.h);
                  walk;
                  menu := 1;
                  drawtitlepic(0, x, y);
                  drawtitlepic(menu + 1, x, y + menu * 20);
                end;
            end;
          end;
        end;
      //鼠标移动
      SDL_MOUSEMOTION:
        begin
          if (event.button.x > x) and (event.button.x < x + 80) and (event.button.y > y) and (event.button.y < y + 60) then
          begin
            menup := menu;
            menu := (event.button.y - y) div 20;
            if menu <> menup then
            begin
              drawtitlepic(0, x, y);
              drawtitlepic(menu + 1, x, y + menu * 20);
              SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            end;
          end;
        end;
    end;
  end;

end;

//开头字幕

procedure StartAmi;
var
  x, y, i, len: integer;
  str: WideString;
  p: integer;
begin
  instruct_14;
  redraw;
  i := fileopen('list\start.txt', fmOpenRead);
  len := fileseek(i, 0, 2);
  fileseek(i, 0, 0);
  setlength(str, len + 1);
  fileread(i, str[1], len);
  fileclose(i);
  p := 1;
  x := 30;
  y := 80;
  drawrectanglewithoutframe(0, 0, CENTER_X * 2, CENTER_Y * 2, 0, 60);
  for i := 1 to len + 1 do
  begin
    if str[i] = widechar(10) then
      str[i] := ' ';
    if str[i] = widechar(13) then
    begin
      str[i] := widechar(0);
      drawshadowtext(@str[p], x, y, colcolor($FF), colcolor($FF));
      p := i + 1;
      y := y + 25;
      sdl_updaterect(screen, 0, 0, screen.w, screen.h);
    end;
    if str[i] = widechar($2A) then
    begin
      str[i] := ' ';
      y := 80;
      redraw;
      waitanykey;
      drawrectanglewithoutframe(0, 50, CENTER_X * 2, CENTER_Y * 2 - 100, 0, 60);
    end;
  end;
  waitanykey;
  instruct_14;
  //instruct_13;

end;

//读取必须的文件

procedure ReadFiles;
var
  grp, idx, tnum, len, col, i: integer;
  filename: string;
  Kys_ini: TIniFile;

begin
  Filename := ExtractFilePath(Paramstr(0)) + 'kysmod.ini';
  Kys_ini := TIniFile.Create(filename);

  try
    ITEM_BEGIN_PIC := Kys_ini.ReadInteger('constant', 'ITEM_BEGIN_PIC', 3501);
    MAX_HEAD_NUM := Kys_ini.ReadInteger('constant', 'MAX_HEAD_NUM', 189);
    BEGIN_EVENT := Kys_ini.ReadInteger('constant', 'BEGIN_EVENT', 691);
    BEGIN_SCENCE := Kys_ini.ReadInteger('constant', 'BEGIN_SCENCE', 70);
    BEGIN_Sx := Kys_ini.ReadInteger('constant', 'BEGIN_Sx', 20);
    BEGIN_Sy := Kys_ini.ReadInteger('constant', 'BEGIN_Sy', 19);
    SOFTSTAR_BEGIN_TALK := Kys_ini.ReadInteger('constant', 'SOFTSTAR_BEGIN_TALK', 2547);
    SOFTSTAR_NUM_TALK := Kys_ini.ReadInteger('constant', 'SOFTSTAR_NUM_TALK', 18);
    MAX_PHYSICAL_POWER := Kys_ini.ReadInteger('constant', 'MAX_PHYSICAL_POWER', 100);
    BEGIN_WALKPIC := Kys_ini.ReadInteger('constant', 'BEGIN_WALKPIC', 2500);
    MONEY_ID := Kys_ini.ReadInteger('constant', 'MONEY_ID', 174);
    COMPASS_ID := Kys_ini.ReadInteger('constant', 'COMPASS_ID', 182);
    BEGIN_LEAVE_EVENT := Kys_ini.ReadInteger('constant', 'BEGIN_LEAVE_EVENT', 950);
    BEGIN_BATTLE_ROLE_PIC := Kys_ini.ReadInteger('constant', 'BEGIN_BATTLE_ROLE_PIC', 2553);
    MAX_LEVEL := Kys_ini.ReadInteger('constant', 'MAX_LEVEL', 30);
    MAX_WEAPON_MATCH := Kys_ini.ReadInteger('constant', 'MAX_WEAPON_MATCH', 7);
    MIN_KNOWLEDGE := Kys_ini.ReadInteger('constant', 'MIN_KNOWLEDGE', 80);
    MAX_HP := Kys_ini.ReadInteger('constant', 'MAX_HP', 999);
    MAX_MP := Kys_ini.ReadInteger('constant', 'MAX_MP', 999);
    LIFE_HURT := Kys_ini.ReadInteger('constant', 'LIFE_HURT', 10);
    NOVEL_BOOK := Kys_ini.ReadInteger('constant', 'NOVEL_BOOK', 144);

    for i := 43 to 58 do
    begin
      MaxProList[i] := Kys_ini.ReadInteger('constant', 'MaxProList' + inttostr(i), 100);
    end;

  finally
    Kys_ini.Free;
  end;
  //showmessage(booltostr(fileexists(filename)));
  //showmessage(inttostr(max_level));

  col := fileopen('resource\mmap.col', fmopenread);
  fileread(col, ACol[0], 768);
  fileclose(col);

  idx := fileopen('resource\mmap.idx', fmopenread);
  grp := fileopen('resource\mmap.grp', fmopenread);
  len := fileseek(grp, 0, 2);
  fileseek(grp, 0, 0);
  fileread(grp, MPic[0], len);
  tnum := fileseek(idx, 0, 2) div 4;
  fileseek(idx, 0, 0);
  fileread(idx, MIdx[0], tnum * 4);
  fileclose(grp);
  fileclose(idx);

  idx := fileopen('resource\sdx', fmopenread);
  grp := fileopen('resource\smp', fmopenread);
  len := fileseek(grp, 0, 2);
  fileseek(grp, 0, 0);
  fileread(grp, SPic[0], len);
  tnum := fileseek(idx, 0, 2) div 4;
  fileseek(idx, 0, 0);
  fileread(idx, SIdx[0], tnum * 4);
  fileclose(grp);
  fileclose(idx);

  idx := fileopen('resource\wdx', fmopenread);
  grp := fileopen('resource\wmp', fmopenread);
  len := fileseek(grp, 0, 2);
  fileseek(grp, 0, 0);
  fileread(grp, WPic[0], len);
  tnum := fileseek(idx, 0, 2) div 4;
  fileseek(idx, 0, 0);
  fileread(idx, WIdx[0], tnum * 4);
  fileclose(grp);
  fileclose(idx);

  idx := fileopen('resource\eft.idx', fmopenread);
  grp := fileopen('resource\eft.grp', fmopenread);
  len := fileseek(grp, 0, 2);
  fileseek(grp, 0, 0);
  fileread(grp, EPic[0], len);
  tnum := fileseek(idx, 0, 2) div 4;
  fileseek(idx, 0, 0);
  fileread(idx, EIdx[0], tnum * 4);
  fileclose(grp);
  fileclose(idx);

  idx := fileopen('resource\hdgrp.idx', fmopenread);
  grp := fileopen('resource\hdgrp.grp', fmopenread);
  len := fileseek(grp, 0, 2);
  fileseek(grp, 0, 0);
  fileread(grp, HPic[0], len);
  tnum := fileseek(idx, 0, 2) div 4;
  fileseek(idx, 0, 0);
  fileread(idx, HIdx[0], tnum * 4);
  fileclose(grp);
  fileclose(idx);

  col := fileopen('resource\earth.002', fmopenread);
  fileread(col, Earth[0, 0], 480 * 480 * 2);
  fileclose(col);
  col := fileopen('resource\surface.002', fmopenread);
  fileread(col, surface[0, 0], 480 * 480 * 2);
  fileclose(col);
  col := fileopen('resource\building.002', fmopenread);
  fileread(col, Building[0, 0], 480 * 480 * 2);
  fileclose(col);
  col := fileopen('resource\buildx.002', fmopenread);
  fileread(col, Buildx[0, 0], 480 * 480 * 2);
  fileclose(col);
  col := fileopen('resource\buildy.002', fmopenread);
  fileread(col, Buildy[0, 0], 480 * 480 * 2);
  fileclose(col);
  col := fileopen('list\leave.bin', fmopenread);
  fileread(col, leavelist[0], 200);
  fileclose(col);
  col := fileopen('list\effect.bin', fmopenread);
  fileread(col, effectlist[0], 200);
  fileclose(col);
  col := fileopen('list\levelup.bin', fmopenread);
  fileread(col, leveluplist[0], 200);
  fileclose(col);
  col := fileopen('list\match.bin', fmopenread);
  fileread(col, matchlist[0], MAX_WEAPON_MATCH * 3 * 2);
  fileclose(col);

end;

//初始化主角属性

procedure InitialRole;
var
  i: integer;
  p: array[0..14] of integer;
  str, str0, name: widestring;
  str1: string;
  p0, p1: Pchar;
begin
  LoadR(0);
  //显示输入姓名的对话框
  //form1.ShowModal;
  //str := form1.edit1.text;
  str := '請以繁體中文輸入主角之姓名，選定屬性後按Esc              ';
  name := InputBox('Enter name', str, '我是主角');
  str1 := unicodetobig5(@name[1]);
  p0 := @rrole[0].Name;
  p1 := @str1[1];
  for i := 0 to 4 do
    rrole[0].Data[4 + i] := 0;
  for i := 0 to 7 do
  begin
    (p0 + i)^ := (p1 + i)^;
  end;
  redraw;
  //showmessage('');
  str := ' 資質';
  repeat
    Rrole[0].MaxHP := 25 + random(26);
    Rrole[0].CurrentHP := Rrole[0].MaxHP;
    Rrole[0].MaxMP := 25 + random(26);
    Rrole[0].CurrentMP := Rrole[0].MaxMP;
    Rrole[0].MPType := random(2);
    Rrole[0].IncLife := 1 + random(10);

    Rrole[0].Attack := 25 + random(6);
    Rrole[0].Speed := 25 + random(6);
    Rrole[0].Defence := 25 + random(6);
    Rrole[0].Medcine := 25 + random(6);
    Rrole[0].UsePoi := 25 + random(6);
    Rrole[0].MedPoi := 25 + random(6);
    Rrole[0].Fist := 25 + random(6);
    Rrole[0].Sword := 25 + random(6);
    Rrole[0].Knife := 25 + random(6);
    Rrole[0].Unusual := 25 + random(6);
    Rrole[0].HidWeapon := 25 + random(6);

    rrole[0].Aptitude := 1 + random(100);
    redraw;
    //showmessage('');
    showstatus(0);
    //showmessage('');
    drawshadowtext(@str[1], 30, CENTER_Y + 111, colcolor($23), colcolor($21));
    str0 := format('%4d', [RRole[0].Aptitude]);
    drawengshadowtext(@str0[1], 150, CENTER_Y + 111, colcolor($66), colcolor($63));
    sdl_updaterect(screen, 0, 0, screen.w, screen.h);
  until waitanykey = sdlk_escape;

  if name = '南宮夢' then
  begin
    Rrole[0].MaxHP := 50;
    Rrole[0].CurrentHP := 50;
    Rrole[0].MaxMP := 50;
    Rrole[0].CurrentMP := 50;
    Rrole[0].MPType := 2;
    Rrole[0].IncLife := 10;

    Rrole[0].Attack := 300;
    Rrole[0].Speed := 30;
    Rrole[0].Defence := 300;
    Rrole[0].Medcine := 300;
    Rrole[0].UsePoi := 30;
    Rrole[0].MedPoi := 30;
    Rrole[0].Fist := 30;
    Rrole[0].Sword := 300;
    Rrole[0].Knife := 30;
    Rrole[0].Unusual := 30;
    Rrole[0].HidWeapon := 300;

    rrole[0].Aptitude := 100;
    rrole[0].Ethics := 95;

  end;

  //redraw;
  showstatus(0);
  drawshadowtext(@str[1], 30, CENTER_Y + 111, colcolor($23), colcolor($21));
  str0 := format('%4d', [RRole[0].Aptitude]);
  drawengshadowtext(@str0[1], 150, CENTER_Y + 111, colcolor($66), colcolor($63));
  sdl_updaterect(screen, 0, 0, screen.w, screen.h);

  StartAmi;
  //EndAmi;

end;

//读入存档, 如为0则读入起始存档

procedure LoadR(num: integer);
var
  filename: string;
  idx, grp, i1, i2, len, ScenceAmount: integer;
  BasicOffset, RoleOffset, ItemOffset, ScenceOffset, MagicOffset, WeiShopOffset, i: integer;
begin
  SaveNum := num;
  filename := 'R' + inttostr(num);

  if num = 0 then
    filename := 'ranger';
  idx := fileopen('save\ranger.idx', fmopenread);
  grp := fileopen('save\' + filename + '.grp', fmopenread);

  fileread(idx, RoleOffset, 4);
  fileread(idx, ItemOffset, 4);
  fileread(idx, ScenceOffset, 4);
  fileread(idx, MagicOffset, 4);
  fileread(idx, WeiShopOffset, 4);
  fileread(idx, len, 4);
  fileseek(grp, 0, 0);

  fileread(grp, Inship, 2);
  fileread(grp, UseLess1, 2);
  fileread(grp, My, 2);
  fileread(grp, Mx, 2);
  fileread(grp, Sy, 2);
  fileread(grp, Sx, 2);
  fileread(grp, Mface, 2);
  fileread(grp, shipx, 2);
  fileread(grp, shipy, 2);
  fileread(grp, shipx1, 2);
  fileread(grp, shipy1, 2);
  fileread(grp, shipface, 2);
  fileread(grp, teamlist[0], 2 * 6);
  fileread(grp, Ritemlist[0], sizeof(Titemlist) * max_item_amount);
  fileread(grp, RRole[0], ItemOffset - RoleOffset);
  fileread(grp, RItem[0], ScenceOffset - ItemOffset);
  fileread(grp, RScence[0], MagicOffset - ScenceOffset);
  fileread(grp, RMagic[0], WeiShopOffset - MagicOffset);
  fileread(grp, Rshop[0], len - WeiShopOffset);
  fileclose(idx);
  fileclose(grp);

  //初始化入口

  ScenceAmount := (MagicOffset - ScenceOffset) div 52;
  for i := 0 to ScenceAmount - 1 do
  begin
    Entrance[RScence[i].MainEntranceX1, RScence[i].MainEntranceY1] := i;
    Entrance[RScence[i].MainEntranceX2, RScence[i].MainEntranceY2] := i;
  end;

  filename := 'S' + inttostr(num);
  if num = 0 then
    filename := 'Allsin';
  grp := fileopen('save\' + filename + '.grp', fmopenread);
  fileread(grp, Sdata, ScenceAmount * 64 * 64 * 6 * 2);
  fileclose(grp);
  filename := 'D' + inttostr(num);
  if num = 0 then
    filename := 'Alldef';
  grp := fileopen('save\' + filename + '.grp', fmopenread);
  fileread(grp, Ddata, ScenceAmount * 200 * 11 * 2);
  fileclose(grp);

end;

//存档

procedure SaveR(num: integer);
var
  filename: string;
  idx, grp, i1, i2, length, ScenceAmount: integer;
  BasicOffset, RoleOffset, ItemOffset, ScenceOffset, MagicOffset, WeiShopOffset, i: integer;
begin
  SaveNum := num;
  filename := 'R' + inttostr(num);

  if num = 0 then
    filename := 'ranger';
  idx := fileopen('save\ranger.idx', fmopenread);
  grp := filecreate('save\' + filename + '.grp', fmopenreadwrite);
  BasicOffset := 0;
  fileread(idx, RoleOffset, 4);
  fileread(idx, ItemOffset, 4);
  fileread(idx, ScenceOffset, 4);
  fileread(idx, MagicOffset, 4);
  fileread(idx, WeiShopOffset, 4);
  fileread(idx, length, 4);
  fileseek(grp, 0, 0);
  filewrite(grp, Inship, 2);
  filewrite(grp, UseLess1, 2);
  filewrite(grp, My, 2);
  filewrite(grp, Mx, 2);
  filewrite(grp, Sy, 2);
  filewrite(grp, Sx, 2);
  filewrite(grp, Mface, 2);
  filewrite(grp, shipx, 2);
  filewrite(grp, shipy, 2);
  filewrite(grp, shipx1, 2);
  filewrite(grp, shipy1, 2);
  filewrite(grp, shipface, 2);
  filewrite(grp, teamlist[0], 2 * 6);
  filewrite(grp, Ritemlist[0], sizeof(Titemlist) * max_item_amount);

  filewrite(grp, RRole[0], ItemOffset - RoleOffset);
  filewrite(grp, RItem[0], ScenceOffset - ItemOffset);
  filewrite(grp, RScence[0], MagicOffset - ScenceOffset);
  filewrite(grp, RMagic[0], WeiShopOffset - MagicOffset);
  filewrite(grp, Rshop[0], length - WeiShopOffset);
  fileclose(idx);
  fileclose(grp);

  ScenceAmount := (MagicOffset - ScenceOffset) div 52;

  filename := 'S' + inttostr(num);
  if num = 0 then
    filename := 'Allsin';
  grp := filecreate('save\' + filename + '.grp');
  filewrite(grp, Sdata, ScenceAmount * 64 * 64 * 6 * 2);
  fileclose(grp);
  filename := 'D' + inttostr(num);
  if num = 0 then
    filename := 'Alldef';
  grp := filecreate('save\' + filename + '.grp');
  filewrite(grp, Ddata, ScenceAmount * 200 * 11 * 2);
  fileclose(grp);

end;

//等待任意按键

function WaitAnyKey: integer;
begin
  //event.type_ := SDL_NOEVENT;
  event.key.keysym.sym := 0;
  event.button.button := 0;
  while (SDL_WaitEvent(@event) >= 0) do
  begin
    if (event.type_ = SDL_QUITEV) then
      if messagedlg('Are you sure to quit?', mtConfirmation, [mbOk, mbCancel], 0) = idOK then
        Quit;
    if (event.type_ = SDL_KEYUP) or (event.type_ = SDL_mousebuttonUP) then
      if (event.key.keysym.sym <> 0) or (event.button.button <> 0) then
        break;
  end;
  result := event.key.keysym.sym;
  event.key.keysym.sym := 0;
  event.button.button := 0;
end;

//于主地图行走

procedure Walk;
var
  word: array[0..10] of Uint16;
  x, y, walking, Mx1, My1, Mx2, My2: integer;
  now, next_time: uint32;
begin
  next_time := sdl_getticks;
  Where := 0;
  walking := 0;
  DrawMMap;
  SDL_EnableKeyRepeat(50, 30);
  StopMp3;
  PlayMp3(16, -1);
  still := 0;
  //ExecScript('test.txt');
  //事件轮询(并非等待)
  while SDL_PollEvent(@event) >= 0 do
  begin
    //如果当前处于标题画面, 则退出, 用于战斗失败
    if where >= 3 then
    begin
      break;
    end;
    //主地图动态效果, 实际仅有主角的动作
    now := sdl_getticks;

    if (integer(now - next_time) > 0) and (Where = 0) then
    begin
      if (Mx2 = Mx) and (My2 = My) then
      begin
        still := 1;
        mstep := mstep + 1;
        if mstep > 6 then
          mstep := 1;
      end;
      Mx2 := Mx;
      My2 := My;
      if still = 1 then
        next_time := now + 500
      else
        next_time := now + 2000;

      DrawMMap;
      SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
      //else next_time:=next_time
    end;
    //如果主角正在行走, 则依据鼠标位置移动主角, 仅用于使用鼠标行走
    if walking = 1 then
    begin
      still := 0;
      sdl_getmousestate(x, y);
      if (x < CENTER_x) and (y < CENTER_y) then
        Mface := 2;
      if (x > CENTER_x) and (y < CENTER_y) then
        Mface := 0;
      if (x < CENTER_x) and (y > CENTER_y) then
        Mface := 3;
      if (x > CENTER_x) and (y > CENTER_y) then
        Mface := 1;
      Mx1 := Mx;
      My1 := My;
      case mface of
        0: Mx1 := Mx1 - 1;
        1: My1 := My1 + 1;
        2: My1 := My1 - 1;
        3: Mx1 := Mx1 + 1;
      end;
      Mstep := Mstep + 1;
      if Mstep > 7 then
        Mstep := 1;
      if canwalk(Mx1, My1) = true then
      begin
        Mx := Mx1;
        My := My1;
      end;
      //每走一步均重画屏幕, 并检测是否处于某场景入口
      DrawMMap;
      //sdl_delay(5);
      SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
      CheckEntrance;
    end;

    case event.type_ of
      SDL_QUITEV:
        if messagedlg('Are you sure to quit?', mtConfirmation, [mbOk, mbCancel], 0) = idOK then
          Quit;
      //方向键使用压下按键事件
      SDL_KEYDOWN:
        begin
          if (event.key.keysym.sym = sdlk_left) then
          begin
            still := 0;
            MFace := 2;
            MStep := Mstep + 1;
            if MStep > 7 then
              MStep := 1;
            if canwalk(Mx, My - 1) = true then
            begin
              My := My - 1;
            end;
            DrawMMap;
            //sdl_delay(5);
            SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            CheckEntrance;
          end;
          if (event.key.keysym.sym = sdlk_right) then
          begin
            still := 0;
            MFace := 1;
            MStep := Mstep + 1;
            if MStep > 7 then
              MStep := 1;
            if canwalk(Mx, My + 1) = true then
            begin
              My := My + 1;
            end;
            DrawMMap;
            //sdl_delay(5);
            SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            CheckEntrance;
          end;
          if (event.key.keysym.sym = sdlk_up) then
          begin
            still := 0;
            MFace := 0;
            MStep := Mstep + 1;
            if MStep > 7 then
              MStep := 1;
            if canwalk(Mx - 1, My) = true then
            begin
              Mx := Mx - 1;
            end;
            DrawMMap;
            //sdl_delay(5);
            SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            CheckEntrance;
          end;
          if (event.key.keysym.sym = sdlk_down) then
          begin
            still := 0;
            MFace := 3;
            MStep := Mstep + 1;
            if MStep > 7 then
              MStep := 1;
            if canwalk(Mx + 1, My) = true then
            begin
              Mx := Mx + 1;
            end;
            DrawMMap;
            //sdl_delay(5);
            SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            CheckEntrance;
          end;
        end;
      //功能键(esc)使用松开按键事件
      SDL_KEYUP:
        begin
          if (event.key.keysym.sym = sdlk_escape) then
          begin
            //event.key.keysym.sym:=0;
            MenuEsc;
            walking := 0;
          end;
          if (event.key.keysym.sym = sdlk_return) and (event.key.keysym.modifier = kmod_lalt) then
          begin
            if fullscreen = 1 then
              screen := SDL_SetVideoMode(CENTER_X * 2, CENTER_Y * 2, 32, SDL_HWSURFACE or SDL_DOUBLEBUF or SDL_ANYFORMAT)
            else
              screen := SDL_SetVideoMode(CENTER_X * 2, CENTER_Y * 2, 32, SDL_FULLSCREEN);
            fullscreen := 1 - fullscreen;
          end;
        end;
      //如按下鼠标左键, 设置状态为行走
      Sdl_mousebuttondown:
        begin
          if event.button.button = sdl_button_left then
          begin
            walking := 1;
          end;
        end;
      //如松开鼠标左键, 设置状态为不行走
      //右键则呼出系统选单
      Sdl_mousebuttonup:
        begin
          if event.button.button = sdl_button_right then
            menuesc;
          if event.button.button = sdl_button_left then
          begin
            walking := 0;
          end;
        end;
    end;
    SDL_Delay(9);
    event.key.keysym.sym := 0;

  end;

  SDL_EnableKeyRepeat(0, 10);

end;

//判定主地图某个位置能否行走, 是否变成船

function CanWalk(x, y: integer): boolean;
begin
  if buildx[x, y] = 0 then
    canwalk := true
  else
    canwalk := false;
  //canwalk:=true;  //This sentence is used to test.
  if (x <= 0) or (x >= 479) or (y <= 0) or (y >= 479) then
    canwalk := false;
  if (earth[x, y] = 838) or ((earth[x, y] >= 612) and (earth[x, y] <= 670)) then
    canwalk := false;
  if ((earth[x, y] >= 358) and (earth[x, y] <= 362))
    or ((earth[x, y] >= 506) and (earth[x, y] <= 670))
    or ((earth[x, y] >= 1016) and (earth[x, y] <= 1022)) then
    InShip := 1
  else
    InShip := 0;
  //canwalk:=true;
end;

//Check able or not to ertrance a scence.
//检测是否处于某入口, 并是否达成进入条件

procedure CheckEntrance;
var
  x, y, i, snum: integer;
  CanEntrance: boolean;
begin
  x := Mx;
  y := My;
  case Mface of
    0: x := x - 1;
    1: y := y + 1;
    2: y := y - 1;
    3: x := x + 1;
  end;
  if (Entrance[x, y] >= 0) then
  begin
    canentrance := false;
    snum := entrance[x, y];
    if (RScence[snum].EnCondition = 0) then
      canentrance := true;
    //是否有人轻功超过70
    if (RScence[snum].EnCondition = 2) then
      for i := 0 to 5 do
        if teamlist[i] >= 0 then
          if Rrole[teamlist[i]].Speed > 70 then
            canentrance := true;
    if canentrance = true then
    begin
      instruct_14;
      CurScence := Entrance[x, y];
      SFace := MFace;
      Mface := 3 - Mface;
      SStep := 1;
      Sx := RScence[CurScence].EntranceX;
      Sy := RScence[CurScence].EntranceY;
      //如达成条件, 进入场景并初始化场景坐标
      SaveR(6);
      InScence(0);
      waitanykey;
    end;
    //instruct_13;
  end;

end;

{
procedure UpdateScenceAmi;
var
  now, next_time: uint32;
  i: integer;
begin

  next_time:=sdl_getticks;
  now:=sdl_getticks;
  while true do
  begin
    now:=sdl_getticks;
    if now>=next_time then
    begin
      LockScence:=true;
      for i:=0 to 199 do
      if DData[CurScence, [i,6]<>DData[CurScence, [i,7] then
      begin
        if (DData[CurScence, [i,5]<5498) or (DData[CurScence, [i,5]>5692) then
        begin
          DData[CurScence, [i,5]:=DData[CurScence, [i,5]+2;
          if DData[CurScence, [i,5]>DData[CurScence, [i,6] then DData[CurScence, [i,5]:=DData[CurScence, [i,7];
          updatescence(DData[CurScence, [i,10],DData[CurScence, [i,9]);
        end;
      end;
      //initialscence;
      sdl_delay(10);
      next_time:=next_time+200;
      LockScence:=false;
    end;
  end;

end;}

//Walk in a scence, the returned value is the scence number when you exit. If it is -1.
//InScence(1) means the new game.
//在内场景行走, 如参数为1表示新游戏

function InScence(open: integer): integer;
var
  grp, idx, offset, just, i1, i2, x, y: integer;
  Sx1, Sy1, s, i, walking, Prescence: integer;
  filename: string;
  scencename: widestring;
  now, next_time: uint32;
  //UpDate: PSDL_Thread;
begin
  //UpDate:=SDL_CreateThread(@UpdateScenceAmi, nil);
  //LockScence:=false;
  next_time := sdl_getticks;
  Where := 1;
  walking := 0;
  just := 0;
  CurEvent := -1;
  SDL_EnableKeyRepeat(50, 30);

  InitialScence;
  if open = 1 then
  begin
    Sx := BEGIN_Sx;
    Sy := BEGIN_Sy;
    Cx := Sx;
    Cy := Sy;
    DrawScence;
    CurEvent := 0;
    SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
    Callevent(BEGIN_EVENT);
    CurEvent := -1;

  end;

  Drawscence;
  ShowScenceName(CurScence);
  //是否有第3类事件位于场景入口
  CheckEvent3;

  while (SDL_PollEvent(@event) >= 0) do
  begin
    if where >= 3 then
    begin
      break;
    end;
    if sx > 63 then
      sx := 63;
    if sy > 63 then
      sy := 63;
    if sx < 0 then
      sx := 0;
    if sy < 0 then
      sy := 0;
    //场景内动态效果
    now := sdl_getticks;
    //next_time:=sdl_getticks;
    if integer(now - next_time) > 0 then
    begin
      for i := 0 to 199 do
        if (DData[CurScence, i, 8] > 0) or (DData[CurScence, i, 7] < DData[CurScence, i, 6]) then
        begin
          //屏蔽了旗子的动态效果, 因贴图太大不好处理
          if (DData[CurScence, i, 5] < 5498) or (DData[CurScence, i, 5] > 5692) then
          begin
            DData[CurScence, i, 5] := DData[CurScence, i, 5] + 2;
            if DData[CurScence, i, 5] > DData[CurScence, i, 6] then
              DData[CurScence, i, 5] := DData[CurScence, i, 7];
            updatescence(DData[CurScence, i, 10], DData[CurScence, i, 9]);
          end;
        end;
      next_time := now + 200;
      DrawScence;
      SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
    end;

    //检查是否位于出口, 如是则退出
    if (((sx = RScence[CurScence].ExitX[0]) and (sy = RScence[CurScence].ExitY[0]))
      or ((sx = RScence[CurScence].ExitX[1]) and (sy = RScence[CurScence].ExitY[1]))
      or ((sx = RScence[CurScence].ExitX[2]) and (sy = RScence[CurScence].ExitY[2]))) then
    begin
      Where := 0;
      result := -1;
      break;
    end;
    //检查是否位于跳转口, 如是则重新初始化场景
    if ((sx = RScence[CurScence].JumpX1) and (sy = RScence[CurScence].JumpY1)) and (RScence[CurScence].JumpScence >= 0) then
    begin
      instruct_14;
      PreScence := CurScence;
      CurScence := Rscence[CurScence].JumpScence;
      if RScence[PreScence].MainEntranceX1 <> 0 then
      begin
        Sx := RScence[CurScence].EntranceX;
        Sy := RScence[CurScence].EntranceY;
      end
      else
      begin
        Sx := RScence[CurScence].JumpX2;
        Sy := RScence[CurScence].JumpY2;
      end;
      {if Sx = 0 then
      begin
        Sx := RScence[CurScence].JumpX2;
        Sy := RScence[CurScence].JumpY2;
      end;
      if Sx = 0 then
      begin
        Sx := RScence[CurScence].EntranceX;
        Sy := RScence[CurScence].EntranceY;
      end;}

      InitialScence;
      Drawscence;
      ShowScenceName(CurScence);
      CheckEvent3;

    end;

    //是否处于行走状态, 参考Walk
    if walking = 1 then
    begin
      sdl_getmousestate(x, y);
      if (x < CENTER_x) and (y < CENTER_y) then
        Sface := 2;
      if (x > CENTER_x) and (y < CENTER_y) then
        Sface := 0;
      if (x < CENTER_x) and (y > CENTER_y) then
        Sface := 3;
      if (x > CENTER_x) and (y > CENTER_y) then
        Sface := 1;
      Sx1 := Sx;
      Sy1 := Sy;
      case Sface of
        0: Sx1 := Sx1 - 1;
        1: Sy1 := Sy1 + 1;
        2: Sy1 := Sy1 - 1;
        3: Sx1 := Sx1 + 1;
      end;
      Sstep := Sstep + 1;
      if Sstep = 8 then
        Sstep := 1;
      if canwalkInScence(Sx1, Sy1) = true then
      begin
        Sx := Sx1;
        Sy := Sy1;

      end;
      DrawScence;
      SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
      CheckEvent3;
    end;

    case event.type_ of
      SDL_QUITEV:
        if messagedlg('Are you sure to quit?', mtConfirmation, [mbOk, mbCancel], 0) = idOK then
          Quit;
      SDL_KEYUP:
        begin
          if (event.key.keysym.sym = sdlk_escape) then
          begin
            MenuEsc;
            walking := 0;
          end;
          //检查是否按下Left Alt+Enter, 是则切换全屏/窗口(似乎并不经常有效)
          if (event.key.keysym.sym = sdlk_return) and (event.key.keysym.modifier = kmod_lalt) then
          begin
            if fullscreen = 1 then
              screen := SDL_SetVideoMode(CENTER_X * 2, CENTER_Y * 2, 32, SDL_HWSURFACE or SDL_DOUBLEBUF or SDL_ANYFORMAT)
            else
              screen := SDL_SetVideoMode(CENTER_X * 2, CENTER_Y * 2, 32, SDL_FULLSCREEN);
            fullscreen := 1 - fullscreen;
          end;
          //按下回车或空格, 检查面对方向是否有第1类事件
          if (event.key.keysym.sym = sdlk_return) or (event.key.keysym.sym = sdlk_space) then
          begin
            x := Sx;
            y := Sy;
            case SFace of
              0: x := x - 1;
              1: y := y + 1;
              2: y := y - 1;
              3: x := x + 1;
            end;
            //如有则调用事件
            if SData[CurScence, 3, x, y] >= 0 then
            begin
              CurEvent := SData[CurScence, 3, x, y];
              walking := 0;
              if DData[CurScence, CurEvent, 2] >= 0 then
                callevent(DData[CurScence, SData[CurScence, 3, x, y], 2]);
            end;
            CurEvent := -1;
          end;

        end;
      SDL_KEYDOWN:
        begin
          if (event.key.keysym.sym = sdlk_left) then
          begin
            SFace := 2;
            SStep := Sstep + 1;
            if SStep = 8 then
              SStep := 1;
            if canwalkinscence(Sx, Sy - 1) = true then
            begin
              Sy := Sy - 1;
            end;
            DrawScence;
            SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            CheckEvent3;
          end;
          if (event.key.keysym.sym = sdlk_right) then
          begin
            SFace := 1;
            SStep := Sstep + 1;
            if SStep = 8 then
              SStep := 1;
            if canwalkinscence(Sx, Sy + 1) = true then
            begin
              Sy := Sy + 1;
            end;
            DrawScence;
            SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            CheckEvent3;
          end;
          if (event.key.keysym.sym = sdlk_up) then
          begin
            SFace := 0;
            SStep := Sstep + 1;
            if SStep = 8 then
              SStep := 1;
            if canwalkinscence(Sx - 1, Sy) = true then
            begin
              Sx := Sx - 1;
            end;
            DrawScence;
            SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            CheckEvent3;
          end;
          if (event.key.keysym.sym = sdlk_down) then
          begin
            SFace := 3;
            SStep := Sstep + 1;
            if SStep = 8 then
              SStep := 1;
            if canwalkinscence(Sx + 1, Sy) = true then
            begin
              Sx := Sx + 1;
            end;
            DrawScence;
            SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            CheckEvent3;
          end;
        end;
      Sdl_mousebuttondown:
        begin
          if event.button.button = sdl_button_left then
          begin
            walking := 1;
          end;
        end;
      Sdl_mousebuttonup:
        begin
          if event.button.button = sdl_button_right then
            menuesc;
          if event.button.button = sdl_button_left then
          begin
            walking := 0;
          end;
        end;
    end;
    sdl_delay(10);
    event.key.keysym.sym := 0;

  end;

  instruct_14; //黑屏

  ReDraw;
  SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
  if Rscence[CurScence].ExitMusic >= 0 then
  begin
    stopmp3;
    playmp3(Rscence[CurScence].ExitMusic, -1);
  end;

end;

procedure ShowScenceName(snum: integer);
var
  scencename: widestring;
begin
  SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
  //显示场景名
  scencename := big5tounicode(@rscence[snum].Name);
  drawtextwithrect(@scencename[1], 320 - length(pchar(@rscence[snum].Name)) * 5 + 7, 100, length(pchar(@rscence[snum].Name)) * 10 + 6, colcolor(7), colcolor(5));
  //waitanykey;
  //改变音乐
  if Rscence[snum].EntranceMusic >= 0 then
  begin
    stopmp3;
    playmp3(Rscence[snum].EntranceMusic, -1);
  end;
  SDL_Delay(500);

end;

//判定场景内某个位置能否行走

function CanWalkInScence(x, y: integer): boolean;
begin
  if (SData[CurScence, 1, x, y] = 0) then
    result := true
  else
    result := false;
  if (SData[CurScence, 3, x, y] >= 0) and (result) and (DData[CurScence, SData[CurScence, 3, x, y], 0] = 1) then
    result := false;
  //直接判定贴图范围
  if ((SData[CurScence, 0, x, y] >= 358) and (SData[CurScence, 0, x, y] <= 362))
    or (SData[CurScence, 0, x, y] = 522) or (SData[CurScence, 0, x, y] = 1022)
    or ((SData[CurScence, 0, x, y] >= 1324) and (SData[CurScence, 0, x, y] <= 1330))
    or (SData[CurScence, 0, x, y] = 1348) then
    result := false;
  //if SData[CurScence, 0, x, y] = 1358 * 2 then result := true;

end;

//检查是否有第3类事件, 如有则调用

procedure CheckEvent3;
var
  enum: integer;
begin
  enum := SData[CurScence, 3, Sx, Sy];
  if (DData[CurScence, enum, 4] > 0) and (enum >= 0) then
  begin
    CurEvent := enum;
    waitanykey;
    callevent(DData[CurScence, enum, 4]);
    CurEvent := -1;
  end;
end;

//Menus.
//通用选单, (位置(x, y), 宽度, 最大选项(编号均从0开始))
//使用前必须设置选单使用的字符串组才有效, 字符串组不可越界使用

function CommonMenu(x, y, w, max: integer): integer;
var
  menu, menup: integer;
begin
  menu := 0;
  //SDL_EnableKeyRepeat(0,10);
  //DrawMMap;
  showcommonMenu(x, y, w, max, menu);
  SDL_UpdateRect(screen, x, y, w + 1, max * 22 + 29);
  while (SDL_WaitEvent(@event) >= 0) do
  begin
    case event.type_ of
      SDL_QUITEV:
        if messagedlg('Are you sure to quit?', mtConfirmation, [mbOk, mbCancel], 0) = idOK then
          Quit;
      SDL_KEYUP:
        begin
          if (event.key.keysym.sym = sdlk_down) then
          begin
            menu := menu + 1;
            if menu > max then
              menu := 0;
            showcommonMenu(x, y, w, max, menu);
            SDL_UpdateRect(screen, x, y, w + 1, max * 22 + 29);
          end;
          if (event.key.keysym.sym = sdlk_up) then
          begin
            menu := menu - 1;
            if menu < 0 then
              menu := max;
            showcommonMenu(x, y, w, max, menu);
            SDL_UpdateRect(screen, x, y, w + 1, max * 22 + 29);
          end;
          if ((event.key.keysym.sym = sdlk_escape)) and (where <= 2) then
          begin
            result := -1;
            ReDraw;
            SDL_UpdateRect(screen, x, y, w + 1, max * 22 + 29);
            break;
          end;
          if (event.key.keysym.sym = sdlk_return) or (event.key.keysym.sym = sdlk_space) then
          begin
            result := menu;
            Redraw;
            SDL_UpdateRect(screen, x, y, w + 1, max * 22 + 29);
            break;
          end;
        end;
      SDL_MOUSEBUTTONUP:
        begin
          if (event.button.button = sdl_button_right) and (where <= 2) then
          begin
            result := -1;
            ReDraw;
            SDL_UpdateRect(screen, x, y, w + 1, max * 22 + 29);
            break;
          end;
          if (event.button.button = sdl_button_left) then
          begin
            result := menu;
            Redraw;
            SDL_UpdateRect(screen, x, y, w + 1, max * 22 + 29);
            break;
          end;
        end;
      SDL_MOUSEMOTION:
        begin
          if (event.button.x >= x) and (event.button.x < x + w) and (event.button.y > y) and (event.button.y < y + max * 22 + 29) then
          begin
            menup := menu;
            menu := (event.button.y - y - 2) div 22;
            if menu > max then
              menu := max;
            if menu < 0 then
              menu := 0;
            if menup <> menu then
            begin
              showcommonMenu(x, y, w, max, menu);
              SDL_UpdateRect(screen, x, y, w + 1, max * 22 + 29);
            end;
          end;
        end;
    end;
  end;
  //清空键盘键和鼠标键值, 避免影响其余部分
  event.key.keysym.sym := 0;
  event.button.button := 0;

end;

//显示通用选单(位置, 宽度, 最大值)
//这个通用选单包含两个字符串组, 可分别显示中文和英文

procedure ShowCommonMenu(x, y, w, max, menu: integer);
var
  i, p: integer;
begin
  redraw;
  DrawRectangle(x, y, w, max * 22 + 28, 0, colcolor(255), 30);
  if length(Menuengstring) > 0 then
    p := 1
  else
    p := 0;
  for i := 0 to max do
    if i = menu then
    begin
      drawshadowtext(@menustring[i][1], x - 17, y + 2 + 22 * i, colcolor($66), colcolor($64));
      if p = 1 then
        drawengshadowtext(@menuengstring[i][1], x + 73, y + 2 + 22 * i, colcolor($66), colcolor($64));
    end
    else
    begin
      drawshadowtext(@menustring[i][1], x - 17, y + 2 + 22 * i, colcolor($7), colcolor($5));
      if p = 1 then
        drawengshadowtext(@menuengstring[i][1], x + 73, y + 2 + 22 * i, colcolor($7), colcolor($5));
    end;

end;

//卷动选单

function CommonScrollMenu(x, y, w, max, maxshow: integer): integer;
var
  menu, menup, menutop: integer;
begin
  menu := 0;
  menutop := 0;
  //SDL_EnableKeyRepeat(0,10);
  //DrawMMap;
  showcommonscrollMenu(x, y, w, max, maxshow, menu, menutop);
  SDL_UpdateRect(screen, x, y, w + 1, maxshow * 22 + 29);
  while (SDL_WaitEvent(@event) >= 0) do
  begin
    case event.type_ of
      SDL_QUITEV:
        if messagedlg('Are you sure to quit?', mtConfirmation, [mbOk, mbCancel], 0) = idOK then
          Quit;
      SDL_KEYUP:
        begin
          if (event.key.keysym.sym = sdlk_down) then
          begin
            menu := menu + 1;
            if menu - menutop >= maxshow then
            begin
              menutop := menutop + 1;
            end;
            if menu > max then
            begin
              menu := 0;
              menutop := 0;
            end;
            showcommonscrollMenu(x, y, w, max, maxshow, menu, menutop);
            SDL_UpdateRect(screen, x, y, w + 1, maxshow * 22 + 29);
          end;
          if (event.key.keysym.sym = sdlk_up) then
          begin
            menu := menu - 1;
            if menu <= menutop then
            begin
              menutop := menu;
            end;
            if menu < 0 then
            begin
              menu := max;
              menutop := menu - maxshow + 1;
            end;
            showcommonscrollMenu(x, y, w, max, maxshow, menu, menutop);
            SDL_UpdateRect(screen, x, y, w + 1, maxshow * 22 + 29);
          end;
          if (event.key.keysym.sym = sdlk_pagedown) then
          begin
            menu := menu + maxshow;
            menutop := menutop + maxshow;
            if menu > max then
            begin
              menu := max;
            end;
            if menutop > max - maxshow + 1 then
            begin
              menutop := max - maxshow + 1;
            end;
            showcommonscrollMenu(x, y, w, max, maxshow, menu, menutop);
            SDL_UpdateRect(screen, x, y, w + 1, maxshow * 22 + 29);
          end;
          if (event.key.keysym.sym = sdlk_pageup) then
          begin
            menu := menu - maxshow;
            menutop := menutop - maxshow;
            if menu < 0 then
            begin
              menu := 0;
            end;
            if menutop < 0 then
            begin
              menutop := 0;
            end;
            showcommonscrollMenu(x, y, w, max, maxshow, menu, menutop);
            SDL_UpdateRect(screen, x, y, w + 1, maxshow * 22 + 29);
          end;
          if ((event.key.keysym.sym = sdlk_escape)) and (where <= 2) then
          begin
            result := -1;
            ReDraw;
            SDL_UpdateRect(screen, x, y, w + 1, maxshow * 22 + 29);
            break;
          end;
          if (event.key.keysym.sym = sdlk_return) or (event.key.keysym.sym = sdlk_space) then
          begin
            result := menu;
            Redraw;
            SDL_UpdateRect(screen, x, y, w + 1, maxshow * 22 + 29);
            break;
          end;
        end;
      SDL_MOUSEBUTTONUP:
        begin
          if (event.button.button = sdl_button_right) and (where <= 2) then
          begin
            result := -1;
            ReDraw;
            SDL_UpdateRect(screen, x, y, w + 1, maxshow * 22 + 29);
            break;
          end;
          if (event.button.button = sdl_button_left) then
          begin
            result := menu;
            Redraw;
            SDL_UpdateRect(screen, x, y, w + 1, maxshow * 22 + 29);
            break;
          end;
          if (event.button.button = sdl_button_wheeldown) then
          begin
            menu := menu + 1;
            if menu - menutop >= maxshow then
            begin
              menutop := menutop + 1;
            end;
            if menu > max then
            begin
              menu := 0;
              menutop := 0;
            end;
            showcommonscrollMenu(x, y, w, max, maxshow, menu, menutop);
            SDL_UpdateRect(screen, x, y, w + 1, maxshow * 22 + 29);
          end;
          if (event.button.button = sdl_button_wheelup) then
          begin
            menu := menu - 1;
            if menu <= menutop then
            begin
              menutop := menu;
            end;
            if menu < 0 then
            begin
              menu := max;
              menutop := menu - maxshow + 1;
            end;
            showcommonscrollMenu(x, y, w, max, maxshow, menu, menutop);
            SDL_UpdateRect(screen, x, y, w + 1, maxshow * 22 + 29);
          end;
        end;
      SDL_MOUSEMOTION:
        begin
          if (event.button.x >= x) and (event.button.x < x + w) and (event.button.y > y) and (event.button.y < y + max * 22 + 29) then
          begin
            menup := menu;
            menu := (event.button.y - y - 2) div 22 + menutop;
            if menu > max then
              menu := max;
            if menu < 0 then
              menu := 0;
            if menup <> menu then
            begin
              showcommonscrollMenu(x, y, w, max, maxshow, menu, menutop);
              SDL_UpdateRect(screen, x, y, w + 1, maxshow * 22 + 29);
            end;
          end;
        end;
    end;
  end;
  //清空键盘键和鼠标键值, 避免影响其余部分
  event.key.keysym.sym := 0;
  event.button.button := 0;

end;

procedure ShowCommonScrollMenu(x, y, w, max, maxshow, menu, menutop: integer);
var
  i, p: integer;
begin
  redraw;
  //showmessage(inttostr(y));
  if max + 1 < maxshow then
    maxshow := max + 1;
  DrawRectangle(x, y, w, maxshow * 22 + 6, 0, colcolor(255), 30);
  if length(Menuengstring) > 0 then
    p := 1
  else
    p := 0;
  for i := menutop to menutop + maxshow - 1 do
    if i = menu then
    begin
      drawshadowtext(@menustring[i][1], x - 17, y + 2 + 22 * (i - menutop), colcolor($66), colcolor($64));
      if p = 1 then
        drawengshadowtext(@menuengstring[i][1], x + 73, y + 2 + 22 * (i - menutop), colcolor($66), colcolor($64));
    end
    else
    begin
      drawshadowtext(@menustring[i][1], x - 17, y + 2 + 22 * (i - menutop), colcolor($7), colcolor($5));
      if p = 1 then
        drawengshadowtext(@menuengstring[i][1], x + 73, y + 2 + 22 * (i - menutop), colcolor($7), colcolor($5));
    end;

end;

//仅有两个选项的横排选单, 为美观使用横排
//此类选单中每个选项限制为两个中文字, 仅适用于提问'继续', '取消'的情况

function CommonMenu2(x, y, w: integer): integer;
var
  menu, menup: integer;
begin
  menu := 0;
  //SDL_EnableKeyRepeat(0,10);
  //DrawMMap;
  showcommonMenu2(x, y, w, menu);
  SDL_UpdateRect(screen, x, y, w + 1, 29);
  while (SDL_WaitEvent(@event) >= 0) do
  begin
    case event.type_ of
      SDL_QUITEV:
        if messagedlg('Are you sure to quit?', mtConfirmation, [mbOk, mbCancel], 0) = idOK then
          Quit;
      SDL_KEYUP:
        begin
          if (event.key.keysym.sym = sdlk_left) or (event.key.keysym.sym = sdlk_right) then
          begin
            if menu = 1 then
              menu := 0
            else
              menu := 1;
            showcommonMenu2(x, y, w, menu);
            SDL_UpdateRect(screen, x, y, w + 1, 29);
          end;
          if ((event.key.keysym.sym = sdlk_escape)) and (where <= 2) then
          begin
            result := -1;
            ReDraw;
            SDL_UpdateRect(screen, x, y, w + 1, 29);
            break;
          end;
          if (event.key.keysym.sym = sdlk_return) or (event.key.keysym.sym = sdlk_space) then
          begin
            result := menu;
            Redraw;
            SDL_UpdateRect(screen, x, y, w + 1, 29);
            break;
          end;
        end;
      SDL_MOUSEBUTTONUP:
        begin
          if (event.button.button = sdl_button_right) and (where <= 2) then
          begin
            result := -1;
            ReDraw;
            SDL_UpdateRect(screen, x, y, w + 1, 29);
            break;
          end;
          if (event.button.button = sdl_button_left) then
          begin
            result := menu;
            Redraw;
            SDL_UpdateRect(screen, x, y, w + 1, 29);
            break;
          end;
        end;
      SDL_MOUSEMOTION:
        begin
          if (event.button.x >= x) and (event.button.x < x + w) and (event.button.y > y) and (event.button.y < y + 29) then
          begin
            menup := menu;
            menu := (event.button.x - x - 2) div 50;
            if menu > 1 then
              menu := 1;
            if menu < 0 then
              menu := 0;
            if menup <> menu then
            begin
              showcommonMenu2(x, y, w, menu);
              SDL_UpdateRect(screen, x, y, w + 1, 29);
            end;
          end;
        end;
    end;
  end;
  //清空键盘键和鼠标键值, 避免影响其余部分
  event.key.keysym.sym := 0;
  event.button.button := 0;

end;

//显示仅有两个选项的横排选单

procedure ShowCommonMenu2(x, y, w, menu: integer);
var
  i, p: integer;
begin
  redraw;
  DrawRectangle(x, y, w, 28, 0, colcolor(255), 30);
  //if length(Menuengstring) > 0 then p := 1 else p := 0;
  for i := 0 to 1 do
    if i = menu then
    begin
      drawshadowtext(@menustring[i][1], x - 17 + i * 50, y + 2, colcolor($66), colcolor($64));
    end
    else
    begin
      drawshadowtext(@menustring[i][1], x - 17 + i * 50, y + 2, colcolor($7), colcolor($5));
    end;

end;

//选择一名队员, 可以附带两个属性显示

function SelectOneTeamMember(x, y: integer; str: string; list1, list2: integer): integer;
var
  i, amount: integer;
begin
  setlength(Menustring, 6);
  if str <> '' then
    setlength(Menuengstring, 6)
  else
    setlength(Menuengstring, 0);
  amount := 0;

  for i := 0 to 5 do
  begin
    if Teamlist[i] >= 0 then
    begin
      menustring[i] := Big5toUnicode(@RRole[Teamlist[i]].Name);
      if str <> '' then
      begin
        menuengstring[i] := format(str, [Rrole[teamlist[i]].data[list1], Rrole[teamlist[i]].data[list2]]);
      end;
      amount := amount + 1;
    end;
  end;
  if str = '' then
    result := commonmenu(x, y, 85, amount - 1)
  else
    result := commonmenu(x, y, 85 + length(menuengstring[0]) * 10, amount - 1);

end;

//主选单

procedure MenuEsc;
var
  menu, menup: integer;
begin
  menu := 0;
  SDL_EnableKeyRepeat(0, 0);
  //DrawMMap;
  showMenu(menu);
  //SDL_EventState(SDL_KEYDOWN,SDL_IGNORE);
  while (SDL_WaitEvent(@event) >= 0) do
  begin
    if where >= 3 then
    begin
      break;
    end;
    case event.type_ of
      SDL_QUITEV:
        if messagedlg('Are you sure to quit?', mtConfirmation, [mbOk, mbCancel], 0) = idOK then
          Quit;
      SDL_KEYUP:
        begin
          if (event.key.keysym.sym = sdlk_down) then
          begin
            menu := menu + 1;
            if menu > 5 - where * 2 then
              menu := 0;
            showMenu(menu);
          end;
          if (event.key.keysym.sym = sdlk_up) then
          begin
            menu := menu - 1;
            if menu < 0 then
              menu := 5 - where * 2;
            showMenu(menu);
          end;
          if (event.key.keysym.sym = sdlk_escape) then
          begin
            ReDraw;
            SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            break;
          end;
          if (event.key.keysym.sym = sdlk_return) or (event.key.keysym.sym = sdlk_space) then
          begin
            case menu of
              0: MenuMedcine;
              1: MenuMedPoision;
              2: MenuItem;
              5: MenuSystem;
              4: MenuLeave;
              3: MenuStatus;
            end;
            showmenu(menu);
          end;
        end;
      SDL_MOUSEBUTTONUP:
        begin
          if event.button.button = sdl_button_right then
          begin
            ReDraw;
            SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            break;
          end;
          if event.button.button = sdl_button_left then
          begin
            if (event.button.y > 32) and (event.button.y < 32 + 22 * (6 - where * 2)) and (event.button.x > 27) and (event.button.x < 27 + 46) then
            begin
              showmenu(menu);
              case menu of
                0: MenuMedcine;
                1: MenuMedPoision;
                2: MenuItem;
                5: MenuSystem;
                4: MenuLeave;
                3: MenuStatus;
              end;
              showmenu(menu);
            end;
          end;
        end;
      SDL_MOUSEMOTION:
        begin
          if (event.button.y > 32) and (event.button.y < 32 + 22 * 6) and (event.button.x > 27) and (event.button.x < 27 + 46) then
          begin
            menup := menu;
            menu := (event.button.y - 32) div 22;
            if menu > 5 - where * 2 then
              menu := 5 - where * 2;
            if menu < 0 then
              menu := 0;
            if menup <> menu then
              showmenu(menu);
          end;
        end;

    end;
  end;
  event.key.keysym.sym := 0;
  event.button.button := 0;
  SDL_EnableKeyRepeat(50, 30);

end;

//显示主选单

procedure ShowMenu(menu: integer);
var
  word: array[0..5] of Widestring;
  i, max: integer;
begin
  Word[0] := ' 醫療';
  Word[1] := ' 解毒';
  Word[2] := ' 物品';
  Word[3] := ' 狀態';
  Word[4] := ' 離隊';
  Word[5] := ' 系統';
  if where = 0 then
    max := 5
  else
    max := 3;
  ReDraw;
  DrawRectangle(27, 30, 46, max * 22 + 28, 0, colcolor(255), 30);
  //当前所在位置用白色, 其余用黄色
  for i := 0 to max do
    if i = menu then
    begin
      drawtext(screen, @word[i][1], 11, 32 + 22 * i, colcolor($64));
      drawtext(screen, @word[i][1], 10, 32 + 22 * i, colcolor($66));
    end
    else
    begin
      drawtext(screen, @word[i][1], 11, 32 + 22 * i, colcolor($5));
      drawtext(screen, @word[i][1], 10, 32 + 22 * i, colcolor($7));
    end;
  SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);

end;

//医疗选单, 需两次选择队员

procedure MenuMedcine;
var
  role1, role2, menu: integer;
  str: widestring;
begin
  str := ' 隊員醫療能力';
  drawtextwithrect(@str[1], 80, 30, 132, colcolor($23), colcolor($21));
  menu := SelectOneTeamMember(80, 65, '%3d', 46, 0);
  showmenu(0);
  SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
  if menu >= 0 then
  begin
    role1 := TeamList[menu];
    str := ' 隊員目前生命';
    drawtextwithrect(@str[1], 80, 30, 132, colcolor($23), colcolor($21));
    menu := SelectOneTeamMember(80, 65, '%4d/%4d', 17, 18);
    role2 := TeamList[menu];
    if menu >= 0 then
      EffectMedcine(role1, role2);
  end;
  //waitanykey;
  redraw;
  //SDL_UpdateRect(screen,0,0,screen.w,screen.h);

end;

//解毒选单

procedure MenuMedPoision;
var
  role1, role2, menu: integer;
  str: widestring;
begin
  str := ' 隊員解毒能力';
  drawtextwithrect(@str[1], 80, 30, 132, colcolor($23), colcolor($21));
  menu := SelectOneTeamMember(80, 65, '%3d', 48, 0);
  showmenu(1);
  SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
  if menu >= 0 then
  begin
    role1 := TeamList[menu];
    str := ' 隊員中毒程度';
    drawtextwithrect(@str[1], 80, 30, 132, colcolor($23), colcolor($21));
    menu := SelectOneTeamMember(80, 65, '%3d', 20, 0);
    role2 := TeamList[menu];
    if menu >= 0 then
      EffectMedPoision(role1, role2);
  end;
  //waitanykey;
  redraw;
  //showmenu(1);
  //SDL_UpdateRect(screen,0,0,screen.w,screen.h);

end;

//物品选单

function MenuItem: boolean;
var
  point, atlu, x, y, col, row, xp, yp, iamount, menu, max: integer;
  //point似乎未使用, atlu为处于左上角的物品在列表中的序号, x, y为光标位置
  //col, row为总列数和行数
begin
  col := 9;
  row := 5;
  x := 0;
  y := 0;
  atlu := 0;
  setlength(Menuengstring, 0);
  case where of
    0, 1:
      begin
        max := 5;
        setlength(menustring, max + 1);
        menustring[0] := ' 全部物品';
        menustring[1] := ' 劇情物品';
        menustring[2] := ' 神兵寶甲';
        menustring[3] := ' 武功秘笈';
        menustring[4] := ' 靈丹妙藥';
        menustring[5] := ' 傷人暗器';
        menu := commonmenu(80, 30, 87, max);
        if menu = 0 then
          menu := 101;
        menu := menu - 1;
      end;
    2:
      begin
        max := 1;
        setlength(menustring, max + 1);
        menustring[0] := ' 靈丹妙藥';
        menustring[1] := ' 傷人暗器';
        menu := commonmenu(150, 150, 87, max);
        if menu >= 0 then
          menu := menu + 3;
      end;
  end;

  if menu < 0 then
    result := false;

  if menu >= 0 then
  begin
    iamount := ReadItemList(menu);
    showMenuItem(row, col, x, y, atlu);
    SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
    while (SDL_WaitEvent(@event) >= 0) do
    begin
      case event.type_ of
        SDL_QUITEV:
          if messagedlg('Are you sure to quit?', mtConfirmation, [mbOk, mbCancel], 0) = idOK then
            Quit;
        SDL_KEYUP:
          begin
            if (event.key.keysym.sym = sdlk_down) then
            begin
              y := y + 1;
              if y < 0 then
                y := 0;
              if (y >= row) then
              begin
                if (ItemList[atlu + col * row] >= 0) then
                  atlu := atlu + col;
                y := row - 1;
              end;
              showMenuItem(row, col, x, y, atlu);
              SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            end;
            if (event.key.keysym.sym = sdlk_up) then
            begin
              y := y - 1;
              if y < 0 then
              begin
                y := 0;
                if atlu > 0 then
                  atlu := atlu - col;
              end;
              showMenuItem(row, col, x, y, atlu);
              SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            end;
            if (event.key.keysym.sym = sdlk_pagedown) then
            begin
              //y := y + row;
              atlu := atlu + col * row;
              if y < 0 then
                y := 0;
              if (ItemList[atlu + col * row] < 0) and (iamount > col * row) then
              begin
                y := y - (iamount - atlu) div col - 1 + row;
                atlu := (iamount div col - row + 1) * col;
                if y >= row then
                  y := row - 1;
              end;
              showMenuItem(row, col, x, y, atlu);
              SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            end;
            if (event.key.keysym.sym = sdlk_pageup) then
            begin
              //y := y - row;
              atlu := atlu - col * row;
              if atlu < 0 then
              begin
                y := y + atlu div col;
                atlu := 0;
                if y < 0 then
                  y := 0;
              end;
              showMenuItem(row, col, x, y, atlu);
              SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            end;
            if (event.key.keysym.sym = sdlk_right) then
            begin
              x := x + 1;
              if x >= col then
                x := 0;
              showMenuItem(row, col, x, y, atlu);
              SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            end;
            if (event.key.keysym.sym = sdlk_left) then
            begin
              x := x - 1;
              if x < 0 then
                x := col - 1;
              showMenuItem(row, col, x, y, atlu);
              SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            end;
            if (event.key.keysym.sym = sdlk_escape) then
            begin
              ReDraw;
              //ShowMenu(2);
              result := false;
              SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
              break;
            end;
            if (event.key.keysym.sym = sdlk_return) or (event.key.keysym.sym = sdlk_space) then
            begin
              ReDraw;
              CurItem := RItemlist[itemlist[(y * col + x + atlu)]].Number;
              if (where <> 2) and (CurItem >= 0) and (itemlist[(y * col + x + atlu)] >= 0) then
                UseItem(CurItem);
              //ShowMenu(2);
              result := true;
              SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
              break;
            end;
          end;
        SDL_MOUSEBUTTONUP:
          begin
            if (event.button.button = sdl_button_right) then
            begin
              ReDraw;
              //ShowMenu(2);
              result := false;
              SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
              break;
            end;
            if (event.button.button = sdl_button_left) then
            begin
              ReDraw;
              CurItem := RItemlist[itemlist[(y * col + x + atlu)]].Number;
              if (where <> 2) and (CurItem >= 0) and (itemlist[(y * col + x + atlu)] >= 0) then
                UseItem(CurItem);
              //ShowMenu(2);
              result := true;
              SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
              break;
            end;
            if (event.button.button = sdl_button_wheeldown) then
            begin
              y := y + 1;
              if y < 0 then
                y := 0;
              if (y >= row) then
              begin
                if (ItemList[atlu + col * 5] >= 0) then
                  atlu := atlu + col;
                y := row - 1;
              end;
              showMenuItem(row, col, x, y, atlu);
              SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            end;
            if (event.button.button = sdl_button_wheelup) then
            begin
              y := y - 1;
              if y < 0 then
              begin
                y := 0;
                if atlu > 0 then
                  atlu := atlu - col;
              end;
              showMenuItem(row, col, x, y, atlu);
              SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            end;
          end;
        SDL_MOUSEMOTION:
          begin
            if (event.button.x >= 110) and (event.button.x < 496) and (event.button.y > 90) and (event.button.y < 308) then
            begin
              xp := x;
              yp := y;
              x := (event.button.x - 115) div 42;
              y := (event.button.y - 95) div 42;
              if x >= col then
                x := col - 1;
              if y >= row then
                y := row - 1;
              if x < 0 then
                x := 0;
              if y < 0 then
                y := 0;
              //鼠标移动时仅在x, y发生变化时才重画
              if (x <> xp) or (y <> yp) then
              begin
                showMenuItem(row, col, x, y, atlu);
                SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
              end;
            end;
            if (event.button.x >= 110) and (event.button.x < 496) and (event.button.y > 308) then
            begin
              //atlu := atlu+col;
              if (ItemList[atlu + col * 5] >= 0) then
                atlu := atlu + col;
              showMenuItem(row, col, x, y, atlu);
              SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            end;
            if (event.button.x >= 110) and (event.button.x < 496) and (event.button.y < 90) then
            begin
              if atlu > 0 then
                atlu := atlu - col;
              showMenuItem(row, col, x, y, atlu);
              SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
            end;
          end;
      end;
    end;
  end;
  //SDL_UpdateRect(screen,0,0,screen.w,screen.h);

end;

//读物品列表, 主要是战斗中需屏蔽一部分物品
//利用一个不可能用到的数值（100），表示读取所有物品

function ReadItemList(ItemType: integer): integer;
var
  i, p: integer;
begin
  p := 0;
  for i := 0 to length(ItemList) - 1 do
    ItemList[i] := -1;
  for i := 0 to MAX_ITEM_AMOUNT - 1 do
  begin
    if (RItemlist[i].Number >= 0) then
    begin
      if (Ritem[RItemlist[i].Number].ItemType = ItemType) or (ItemType = 100) then
      begin
        Itemlist[p] := i;
        p := p + 1;
      end;
    end;
  end;
  result := p;

end;

//显示物品选单

procedure ShowMenuItem(row, col, x, y, atlu: integer);
var
  item, i, i1, i2, len, len2, len3, listnum: integer;
  str: widestring;
  words: array[0..10] of widestring;
  words2: array[0..22] of widestring;
  words3: array[0..12] of widestring;
  p2: array[0..22] of integer;
  p3: array[0..12] of integer;
begin
  words[0] := ' 劇情物品';
  words[1] := ' 神兵寶甲';
  words[2] := ' 武功秘笈';
  words[3] := ' 靈丹妙藥';
  words[4] := ' 傷人暗器';
  words2[0] := ' 生命';
  words2[1] := ' 生命';
  words2[2] := ' 中毒';
  words2[3] := ' 體力';
  words2[4] := ' 內力';
  words2[5] := ' 內力';
  words2[6] := ' 內力';
  words2[7] := ' 攻擊';
  words2[8] := ' 輕功';
  words2[9] := ' 防禦';
  words2[10] := ' 醫療';
  words2[11] := ' 用毒';
  words2[12] := ' 解毒';
  words2[13] := ' 抗毒';
  words2[14] := ' 拳掌';
  words2[15] := ' 御劍';
  words2[16] := ' 耍刀';
  words2[17] := ' 特殊';
  words2[18] := ' 暗器';
  words2[19] := ' 武學';
  words2[20] := ' 品德';
  words2[21] := ' 左右';
  words2[22] := ' 帶毒';

  words3[0] := ' 內力';
  words3[1] := ' 內力';
  words3[2] := ' 攻擊';
  words3[3] := ' 輕功';
  words3[4] := ' 用毒';
  words3[5] := ' 醫療';
  words3[6] := ' 解毒';
  words3[7] := ' 拳掌';
  words3[8] := ' 御劍';
  words3[9] := ' 耍刀';
  words3[10] := ' 特殊';
  words3[11] := ' 暗器';
  words3[12] := ' 資質';

  ReDraw;
  drawrectangle(110, 30, 386, 25, 0, colcolor(255), 30);
  drawrectangle(110, 60, 386, 25, 0, colcolor(255), 30);
  drawrectangle(110, 90, 386, 218, 0, colcolor(255), 30);
  drawrectangle(110, 313, 386, 25, 0, colcolor(255), 30);
  //i:=0;
  for i1 := 0 to row - 1 do
    for i2 := 0 to col - 1 do
    begin
      listnum := ItemList[i1 * col + i2 + atlu];
      if (RItemlist[listnum].Number >= 0) and (listnum < MAX_ITEM_AMOUNT) and (listnum >= 0) then
      begin
        DrawMPic(ITEM_BEGIN_PIC + RItemlist[listnum].Number, i2 * 42 + 115, i1 * 42 + 95);
      end;
    end;
  listnum := itemlist[y * col + x + atlu];
  if listnum in [0..MAX_ITEM_AMOUNT] then
    item := RItemlist[listnum].Number
  else
    item := -1;

  if (RItemlist[listnum].Amount > 0) and (listnum < MAX_ITEM_AMOUNT) and (listnum >= 0) then
  begin
    str := format('%5d', [RItemlist[listnum].Amount]);
    drawengtext(screen, @str[1], 431, 32, colcolor($64));
    drawengtext(screen, @str[1], 430, 32, colcolor($66));
    len := length(pchar(@Ritem[item].Name));
    drawbig5text(screen, @RItem[item].Name, 296 - len * 5, 32, colcolor($21));
    drawbig5text(screen, @RItem[item].Name, 295 - len * 5, 32, colcolor($23));
    len := length(pchar(@Ritem[item].Introduction));
    drawbig5text(screen, @RItem[item].Introduction, 296 - len * 5, 62, colcolor($5));
    drawbig5text(screen, @RItem[item].Introduction, 295 - len * 5, 62, colcolor($7));
    drawshadowtext(@words[Ritem[item].ItemType, 1], 97, 315, colcolor($23), colcolor($21));
    //如有人使用则显示
    if RItem[item].User >= 0 then
    begin
      str := ' 使用人：';
      drawshadowtext(@str[1], 187, 315, colcolor($23), colcolor($21));
      drawbig5shadowtext(@rrole[RItem[item].User].Name, 277, 315, colcolor($66), colcolor($64));
    end;
    //如是罗盘则显示坐标
    if item = COMPASS_ID then
    begin
      str := ' 你的位置：';
      drawshadowtext(@str[1], 187, 315, colcolor($23), colcolor($21));
      str := format('%3d, %3d', [My, Mx]);
      drawengshadowtext(@str[1], 317, 315, colcolor($66), colcolor($64));
    end;
  end;

  if (item >= 0) and (ritem[item].ItemType > 0) then
  begin
    len2 := 0;
    for i := 0 to 22 do
    begin
      p2[i] := 0;
      if (ritem[item].Data[45 + i] <> 0) and (i <> 4) then
      begin
        p2[i] := 1;
        len2 := len2 + 1;
      end;
    end;
    if ritem[item].ChangeMPType = 2 then
    begin
      p2[4] := 1;
      len2 := len2 + 1;
    end;

    len3 := 0;
    for i := 0 to 12 do
    begin
      p3[i] := 0;
      if (ritem[item].Data[69 + i] <> 0) and (i <> 0) then
      begin
        p3[i] := 1;
        len3 := len3 + 1;
      end;
    end;
    if (ritem[item].NeedMPType in [0, 1]) and (ritem[item].ItemType <> 3) then
    begin
      p3[0] := 1;
      len3 := len3 + 1;
    end;

    if len2 + len3 > 0 then
      drawrectangle(110, 344, 386, 20 * ((len2 + 2) div 3 + (len3 + 2) div 3) + 5, 0, colcolor(255), 30);

    i1 := 0;
    for i := 0 to 22 do
    begin
      if (p2[i] = 1) then
      begin
        str := format('%6d', [ritem[item].Data[45 + i]]);
        if i = 4 then
          case ritem[item].ChangeMPType of
            0: str := '    陰';
            1: str := '    陽';
            2: str := '  調和';
          end;

        drawshadowtext(@words2[i][1], 97 + i1 mod 3 * 130, i1 div 3 * 20 + 346, colcolor($7), colcolor($5));
        drawshadowtext(@str[1], 147 + i1 mod 3 * 130, i1 div 3 * 20 + 346, colcolor($66), colcolor($64));
        i1 := i1 + 1;
      end;
    end;

    i1 := 0;
    for i := 0 to 12 do
    begin
      if (p3[i] = 1) then
      begin
        str := format('%6d', [ritem[item].Data[69 + i]]);
        if i = 0 then
          case ritem[item].NeedMPType of
            0: str := '    陰';
            1: str := '    陽';
            2: str := '  調和';
          end;

        drawshadowtext(@words3[i][1], 97 + i1 mod 3 * 130, ((len2 + 2) div 3 + i1 div 3) * 20 + 346, colcolor($50), colcolor($4E));
        drawshadowtext(@str[1], 147 + i1 mod 3 * 130, ((len2 + 2) div 3 + i1 div 3) * 20 + 346, colcolor($66), colcolor($64));
        i1 := i1 + 1;
      end;
    end;
  end;

  drawItemframe(x, y);

end;

//画白色边框作为物品选单的光标

procedure DrawItemFrame(x, y: integer);
var
  i: integer;
begin
  for i := 0 to 39 do
  begin
    putpixel(screen, x * 42 + 116 + i, y * 42 + 96, colcolor(255));
    putpixel(screen, x * 42 + 116 + i, y * 42 + 96 + 39, colcolor(255));
    putpixel(screen, x * 42 + 116, y * 42 + 96 + i, colcolor(255));
    putpixel(screen, x * 42 + 116 + 39, y * 42 + 96 + i, colcolor(255));
  end;

end;

//使用物品

procedure UseItem(inum: integer);
var
  x, y, menu, rnum, p: integer;
  str, str1: widestring;
begin
  CurItem := inum;

  case RItem[inum].ItemType of
    0: //剧情物品
      begin
        //如某属性大于0, 直接调用事件
        if ritem[inum].UnKnow7 > 0 then
          callevent(ritem[inum].UnKnow7)
        else
        begin
          if where = 1 then
          begin
            x := Sx;
            y := Sy;
            case SFace of
              0: x := x - 1;
              1: y := y + 1;
              2: y := y - 1;
              3: x := x + 1;
            end;
            //如面向位置有第2类事件则调用
            if SData[CurScence, 3, x, y] >= 0 then
            begin
              CurEvent := SData[CurScence, 3, x, y];
              if DData[CurScence, SData[CurScence, 3, x, y], 3] >= 0 then
                callevent(DData[CurScence, SData[CurScence, 3, x, y], 3]);
            end;
            CurEvent := -1;
          end;
        end;
      end;
    1: //装备
      begin
        menu := 1;
        if Ritem[inum].User >= 0 then
        begin
          setlength(menustring, 2);
          menustring[0] := ' 取消';
          menustring[1] := ' 繼續';
          str := ' 此物品正有人裝備，是否繼續？';
          drawtextwithrect(@str[1], 80, 30, 285, colcolor(7), colcolor(5));
          menu := commonmenu(80, 65, 45, 1);
        end;
        if menu = 1 then
        begin
          str := ' 誰要裝備';
          str1 := big5tounicode(@Ritem[inum].Name);
          drawtextwithrect(@str[1], 80, 30, length(str1) * 22 + 80, colcolor($23), colcolor($21));
          drawshadowtext(@str1[1], 160, 32, colcolor($66), colcolor($64));
          SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
          menu := SelectOneTeamMember(80, 65, '', 0, 0);
          if menu >= 0 then
          begin
            rnum := Teamlist[menu];
            p := Ritem[inum].EquipType;
            if (p < 0) or (p > 1) then
              p := 0;
            if canequip(rnum, inum) then
            begin
              if Ritem[inum].User >= 0 then
                Rrole[Ritem[inum].User].Equip[p] := -1;
              if Rrole[rnum].Equip[p] >= 0 then
                Ritem[RRole[rnum].Equip[p]].User := -1;
              Rrole[rnum].Equip[p] := inum;
              Ritem[inum].User := rnum;
            end
            else
            begin
              str := ' 此人不適合裝備此物品';
              drawtextwithrect(@str[1], 80, 30, 205, colcolor($66), colcolor($64));
              waitanykey;
              redraw;
              //SDL_UpdateRect(screen,0,0,screen.w,screen.h);
            end;
          end;
        end;
      end;
    2: //秘笈
      begin
        menu := 1;
        if Ritem[inum].User >= 0 then
        begin
          setlength(menustring, 2);
          menustring[0] := ' 取消';
          menustring[1] := ' 繼續';
          str := ' 此秘笈正有人修煉，是否繼續？';
          drawtextwithrect(@str[1], 80, 30, 285, colcolor(7), colcolor(5));
          menu := commonmenu(80, 65, 45, 1);
        end;
        if menu = 1 then
        begin
          str := ' 誰要修煉';
          str1 := big5tounicode(@Ritem[inum].Name);
          drawtextwithrect(@str[1], 80, 30, length(str1) * 22 + 80, colcolor($23), colcolor($21));
          drawshadowtext(@str1[1], 160, 32, colcolor($66), colcolor($64));
          SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
          menu := SelectOneTeamMember(80, 65, '', 0, 0);
          if menu >= 0 then
          begin
            rnum := TeamList[menu];
            if canequip(rnum, inum) then
            begin
              if Ritem[inum].User >= 0 then
                Rrole[Ritem[inum].User].PracticeBook := -1;
              if Rrole[rnum].PracticeBook >= 0 then
                Ritem[RRole[rnum].PracticeBook].User := -1;
              Rrole[rnum].PracticeBook := inum;
              Ritem[inum].User := rnum;
              if (inum in [78, 93]) then
                rrole[rnum].Sexual := 2;
            end
            else
            begin
              str := ' 此人不適合修煉此秘笈';
              drawtextwithrect(@str[1], 80, 30, 205, colcolor($66), colcolor($64));
              waitanykey;
              redraw;
              //SDL_UpdateRect(screen,0,0,screen.w,screen.h);
            end;
          end;
        end;
      end;
    3: //药品
      begin
        if where <> 2 then
        begin
          str := ' 誰要服用';
          str1 := big5tounicode(@Ritem[inum].Name);
          drawtextwithrect(@str[1], 80, 30, length(str1) * 22 + 80, colcolor($23), colcolor($21));
          drawshadowtext(@str1[1], 160, 32, colcolor($66), colcolor($64));
          SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
          menu := SelectOneTeamMember(80, 65, '', 0, 0);
          rnum := TeamList[menu];
        end;
        if menu >= 0 then
        begin
          redraw;
          EatOneItem(rnum, inum);
          instruct_32(inum, -1);
          waitanykey;
        end;
      end;
    4: //不处理暗器类物品
      begin
        //if where<>3 then break;
      end;
  end;

end;

//能否装备

function CanEquip(rnum, inum: integer): boolean;
var
  i, r: integer;
begin

  //判断是否符合
  //注意这里对'所需属性'为负值时均添加原版类似资质的处理

  result := true;

  if sign(Ritem[inum].NeedMP) * Rrole[rnum].CurrentMP < Ritem[inum].NeedMP then
    result := false;
  if sign(Ritem[inum].NeedAttack) * Rrole[rnum].Attack < Ritem[inum].NeedAttack then
    result := false;
  if sign(Ritem[inum].NeedSpeed) * Rrole[rnum].Speed < Ritem[inum].NeedSpeed then
    result := false;
  if sign(Ritem[inum].NeedUsePoi) * Rrole[rnum].UsePoi < Ritem[inum].NeedUsepoi then
    result := false;
  if sign(Ritem[inum].NeedMedcine) * Rrole[rnum].Medcine < Ritem[inum].NeedMedcine then
    result := false;
  if sign(Ritem[inum].NeedMedPoi) * Rrole[rnum].MedPoi < Ritem[inum].NeedMedPoi then
    result := false;
  if sign(Ritem[inum].NeedFist) * Rrole[rnum].Fist < Ritem[inum].NeedFist then
    result := false;
  if sign(Ritem[inum].NeedSword) * Rrole[rnum].Sword < Ritem[inum].NeedSword then
    result := false;
  if sign(Ritem[inum].NeedKnife) * Rrole[rnum].Knife < Ritem[inum].NeedKnife then
    result := false;
  if sign(Ritem[inum].NeedUnusual) * Rrole[rnum].Unusual < Ritem[inum].NeedUnusual then
    result := false;
  if sign(Ritem[inum].NeedHidWeapon) * Rrole[rnum].HidWeapon < Ritem[inum].NeedHidWeapon then
    result := false;
  if sign(Ritem[inum].NeedAptitude) * Rrole[rnum].Aptitude < Ritem[inum].NeedAptitude then
    result := false;

  //内力性质
  if (rrole[rnum].MPType < 2) and (Ritem[inum].NeedMPType < 2) then
    if rrole[rnum].MPType <> Ritem[inum].NeedMPType then
      result := false;

  //如有专用人物, 前面的都作废
  if (Ritem[inum].OnlyPracRole >= 0) and (result = true) then
    if (Ritem[inum].OnlyPracRole = rnum) then
      result := true
    else
      result := false;

  //如已有10种武功, 且物品也能练出武功, 则结果为假
  r := 0;
  for i := 0 to 9 do
    if Rrole[rnum].Magic[i] > 0 then
      r := r + 1;
  if (r >= 10) and (ritem[inum].Magic > 0) then
    result := false;

  for i := 0 to 9 do
    if Rrole[rnum].Magic[i] = ritem[inum].Magic then
    begin
      result := true;
      break;
    end;

end;

//查看状态选单

procedure MenuStatus;
var
  str: widestring;
  menu: integer;
begin
  str := ' 查看隊員狀態';
  drawtextwithrect(@str[1], 80, 30, 132, colcolor($23), colcolor($21));
  menu := SelectOneTeamMember(80, 65, '%3d', 15, 0);
  if menu >= 0 then
  begin
    ShowStatus(TeamList[menu]);
    waitanykey;
    redraw;
    SDL_UpdateRect(screen, 0, 0, screen.w, screen.h);
  end;

end;

//显示状态

procedure ShowStatus(rnum: integer);
var
  i, magicnum, mlevel, needexp, x, y: integer;
  p: array[0..10] of integer;
  addatk, adddef, addspeed: integer;
  str: widestring;
  strs: array[0..21] of widestring;
  color1, color2: uint32;
  name: widestring;
begin
  strs[0] := ' 等級';
  strs[1] := ' 生命';
  strs[2] := ' 內力';
  strs[3] := ' 體力';
  strs[4] := ' 經驗';
  strs[5] := ' 升級';
  strs[6] := ' 攻擊';
  strs[7] := ' 防禦';
  strs[8] := ' 輕功';
  strs[9] := ' 醫療能力';
  strs[10] := ' 用毒能力';
  strs[11] := ' 解毒能力';
  strs[12] := ' 拳掌功夫';
  strs[13] := ' 御劍能力';
  strs[14] := ' 耍刀技巧';
  strs[15] := ' 特殊兵器';
  strs[16] := ' 暗器技巧';
  strs[17] := ' 裝備物品';
  strs[18] := ' 修煉物品';
  strs[19] := ' 所會武功';
  strs[20] := ' 受傷';
  strs[21] := ' 中毒';
  p[0] := 43;
  p[1] := 45;
  p[2] := 44;
  p[3] := 46;
  p[4] := 47;
  p[5] := 48;
  p[6] := 50;
  p[7] := 51;
  p[8] := 52;
  p[9] := 53;
  p[10] := 54;
  Redraw;
  x := 40;
  y := CENTER_Y - 160;

  DrawRectangle(x, y, 560, 315, 0, colcolor(255), 50);
  //显示头像
  drawheadpic(Rrole[rnum].HeadNum, x + 60, y + 80);
  //显示姓名
  name := big5tounicode(@Rrole[rnum].Name);
  drawshadowtext(@name[1], x + 68 - length(pchar(@Rrole[rnum].Name)) * 5, y + 85, colcolor($66), colcolor($63));
  //显示所需字符
  for i := 0 to 5 do
    drawshadowtext(@strs[i, 1], x - 10, y + 110 + 21 * i, colcolor($23), colcolor($21));
  for i := 6 to 16 do
    drawshadowtext(@strs[i, 1], x + 160, y + 5 + 21 * (i - 6), colcolor($66), colcolor($63));
  drawshadowtext(@strs[19, 1], x + 360, y + 5, colcolor($23), colcolor($21));

  addatk := 0;
  adddef := 0;
  addspeed := 0;
  if rrole[rnum].Equip[0] >= 0 then
  begin
    addatk := addatk + ritem[rrole[rnum].Equip[0]].AddAttack;
    adddef := adddef + ritem[rrole[rnum].Equip[0]].AddDefence;
    addspeed := addspeed + ritem[rrole[rnum].Equip[0]].AddSpeed;
  end;

  if rrole[rnum].Equip[1] >= 0 then
  begin
    addatk := addatk + ritem[rrole[rnum].Equip[1]].AddAttack;
    adddef := adddef + ritem[rrole[rnum].Equip[1]].AddDefence;
    addspeed := addspeed + ritem[rrole[rnum].Equip[1]].AddSpeed;
  end;

  //攻击, 防御, 轻功
  //单独处理是因为显示顺序和存储顺序不同
  str := format('%4d', [Rrole[rnum].Attack + addatk]);
  drawengshadowtext(@str[1], x + 300, y + 5 + 21 * 0, colcolor($7), colcolor($5));
  str := format('%4d', [Rrole[rnum].Defence + adddef]);
  drawengshadowtext(@str[1], x + 300, y + 5 + 21 * 1, colcolor($7), colcolor($5));
  str := format('%4d', [Rrole[rnum].Speed + addspeed]);
  drawengshadowtext(@str[1], x + 300, y + 5 + 21 * 2, colcolor($7), colcolor($5));

  //其他属性
  str := format('%4d', [Rrole[rnum].Medcine]);
  drawengshadowtext(@str[1], x + 300, y + 5 + 21 * 3, colcolor($7), colcolor($5));

  str := format('%4d', [Rrole[rnum].UsePoi]);
  drawengshadowtext(@str[1], x + 300, y + 5 + 21 * 4, colcolor($7), colcolor($5));

  str := format('%4d', [Rrole[rnum].MedPoi]);
  drawengshadowtext(@str[1], x + 300, y + 5 + 21 * 5, colcolor($7), colcolor($5));

  str := format('%4d', [Rrole[rnum].Fist]);
  drawengshadowtext(@str[1], x + 300, y + 5 + 21 * 6, colcolor($7), colcolor($5));

  str := format('%4d', [Rrole[rnum].Sword]);
  drawengshadowtext(@str[1], x + 300, y + 5 + 21 * 7, colcolor($7), colcolor($5));

  str := format('%4d', [Rrole[rnum].Knife]);
  drawengshadowtext(@str[1], x + 300, y + 5 + 21 * 8, colcolor($7), colcolor($5));

  str := format('%4d', [Rrole[rnum].Unusual]);
  drawengshadowtext(@str[1], x + 300, y + 5 + 21 * 9, colcolor($7), colcolor($5));

  str := format('%4d', [Rrole[rnum].HidWeapon]);
  drawengshadowtext(@str[1], x + 300, y + 5 + 21 * 10, colcolor($7), colcolor($5));

  //武功
  for i := 0 to 9 do
  begin
    magicnum := Rrole[rnum].magic[i];
    if magicnum > 0 then
    begin
      drawbig5shadowtext(@Rmagic[magicnum].Name, x + 360, y + 26 + 21 * i, colcolor($7), colcolor($5));
      str := format('%3d', [Rrole[rnum].MagLevel[i] div 100 + 1]);
      drawengshadowtext(@str[1], x + 520, y + 26 + 21 * i, colcolor($66), colcolor($64));
    end;
  end;
  str := format('%4d', [Rrole[rnum].Level]);
  drawengshadowtext(@str[1], x + 110, y + 110, colcolor($7), colcolor($5));
  //生命值, 在受伤和中毒值不同时使用不同颜色
  case RRole[rnum].Hurt of
    34..66:
      begin
        color1 := colcolor($E);
        color2 := colcolor($10);
      end;
    67..1000:
      begin
        color1 := colcolor($14);
        color2 := colcolor($16);
      end;
  else
    begin
      color1 := colcolor($7);
      color2 := colcolor($5);
    end;
  end;
  str := format('%4d', [RRole[rnum].CurrentHP]);
  drawengshadowtext(@str[1], x + 60, y + 131, color1, color2);

  str := '/';
  drawengshadowtext(@str[1], x + 100, y + 131, colcolor($66), colcolor($63));

  case RRole[rnum].Poision of
    34..66:
      begin
        color1 := colcolor($30);
        color2 := colcolor($32);
      end;
    67..1000:
      begin
        color1 := colcolor($35);
        color2 := colcolor($37);
      end;
  else
    begin
      color1 := colcolor($23);
      color2 := colcolor($21);
    end;
  end;
  str := format('%4d', [RRole[rnum].MaxHP]);
  drawengshadowtext(@str[1], x + 110, y + 131, color1, color2);
  //内力, 依据内力性质使用颜色
  if rrole[rnum].MPType = 0 then
  begin
    color1 := colcolor($50);
    color2 := colcolor($4E);
  end
  else if rrole[rnum].MPType = 1 then
  begin
    color1 := colcolor($7);
    color2 := colcolor($5);
  end
  else
  begin
    color1 := colcolor($66);
    color2 := colcolor($63);
  end;
  str := format('%4d/%4d', [RRole[rnum].CurrentMP, RRole[rnum].MaxMP]);
  drawengshadowtext(@str[1], x + 60, y + 152, color1, color2);
  //体力
  str := format('%4d/%4d', [rrole[rnum].PhyPower, MAX_PHYSICAL_POWER]);
  drawengshadowtext(@str[1], x + 60, y + 173, colcolor($7), colcolor($5));
  //经验
  str := format('%5d', [uint16(Rrole[rnum].Exp)]);
  drawengshadowtext(@str[1], x + 100, y + 194, colcolor($7), colcolor($5));
  str := format('%5d', [uint16(Leveluplist[Rrole[rnum].Level - 1])]);
  drawengshadowtext(@str[1], x + 100, y + 215, colcolor($7), colcolor($5));

  //str:=format('%5d', [Rrole[rnum,21]]);
  //drawengshadowtext(@str[1],150,295,colcolor($7),colcolor($5));

  //drawshadowtext(@strs[20, 1], 30, 341, colcolor($23), colcolor($21));
  //drawshadowtext(@strs[21, 1], 30, 362, colcolor($23), colcolor($21));

  //drawrectanglewithoutframe(100,351,Rrole[rnum,19],10,colcolor($16),50);
  //中毒, 受伤
  //str := format('%4d', [RRole[rnum].Hurt]);
  //drawengshadowtext(@str[1], 150, 341, colcolor($14), colcolor($16));
  //str := format('%4d', [RRole[rnum].Poision]);
  //drawengshadowtext(@str[1], 150, 362, colcolor($35), colcolor($37));

  //装备, 秘笈
  drawshadowtext(@strs[17, 1], x + 160, y + 240, colcolor($23), colcolor($21));
  drawshadowtext(@strs[18, 1], x + 360, y + 240, colcolor($23), colcolor($21));
  if Rrole[rnum].Equip[0] >= 0 then
    drawbig5shadowtext(@Ritem[Rrole[rnum].Equip[0]].Name, x + 170, y + 261, colcolor($7), colcolor($5));
  if Rrole[rnum].Equip[1] >= 0 then
    drawbig5shadowtext(@Ritem[Rrole[rnum].Equip[1]].Name, x + 170, y + 282, colcolor($7), colcolor($5));

  //计算秘笈需要经验
  if Rrole[rnum].PracticeBook >= 0 then
  begin
    mlevel := 1;
    magicnum := Ritem[Rrole[rnum].PracticeBook].Magic;
    if magicnum > 0 then
      for i := 0 to 9 do
        if Rrole[rnum].Magic[i] = magicnum then
        begin
          mlevel := Rrole[rnum].MagLevel[i] div 100 + 1;
          break;
        end;
    needexp := mlevel * Ritem[Rrole[rnum].PracticeBook].NeedExp * (7 - Rrole[rnum].Aptitude div 15);
    drawbig5shadowtext(@Ritem[Rrole[rnum].PracticeBook].Name, x + 370, y + 261, colcolor($7), colcolor($5));
    str := format('%5d/%5d', [uint16(Rrole[rnum].ExpForBook), needexp]);
    if mlevel = 10 then
      str := format('%5d/=', [uint16(Rrole[rnum].ExpForBook)]);
    drawengshadowtext(@str[1], x + 400, y + 282, colcolor($66), colcolor($63));
  end;

  SDL_UpdateRect(screen, x, y, 561, 316);

end;

//离队选单

procedure MenuLeave;
var
  str: widestring;
  i, menu: integer;
begin
  str := ' 要求誰離隊？';
  drawtextwithrect(@str[1], 80, 30, 132, colcolor($23), colcolor($21));
  menu := SelectOneTeamMember(80, 65, '%3d', 15, 0);
  if menu >= 0 then
  begin
    for i := 0 to 99 do
      if leavelist[i] = TeamList[menu] then
      begin
        callevent(BEGIN_LEAVE_EVENT + i * 2);
        SDL_EnableKeyRepeat(0, 10);
        break;
      end;
  end;
  redraw;

end;

//系统选单

procedure MenuSystem;
var
  i, menu, menup: integer;
begin
  menu := 0;
  showmenusystem(menu);
  while (SDL_WaitEvent(@event) >= 0) do
  begin
    if where = 3 then
      break;
    case event.type_ of
      SDL_QUITEV:
        if messagedlg('Are you sure to quit?', mtConfirmation, [mbOk, mbCancel], 0) = idOK then
          Quit;
      SDL_KEYUP:
        begin
          if (event.key.keysym.sym = sdlk_down) then
          begin
            menu := menu + 1;
            if menu > 3 then
              menu := 0;
            showMenusystem(menu);
          end;
          if (event.key.keysym.sym = sdlk_up) then
          begin
            menu := menu - 1;
            if menu < 0 then
              menu := 3;
            showMenusystem(menu);
          end;
          if (event.key.keysym.sym = sdlk_escape) then
          begin
            redraw;
            SDL_UpdateRect(screen, 80, 30, 47, 95);
            break;
          end;
          if (event.key.keysym.sym = sdlk_return) or (event.key.keysym.sym = sdlk_space) then
          begin
            case menu of
              3:
                begin
                  MenuQuit;
                end;
              1:
                begin
                  MenuSave;
                end;
              0:
                begin
                  Menuload;
                end;
              2:
                begin
                  if fullscreen = 1 then
                    screen := SDL_SetVideoMode(CENTER_X * 2, CENTER_Y * 2, 32, SDL_HWSURFACE or SDL_DOUBLEBUF or SDL_ANYFORMAT)
                  else
                    screen := SDL_SetVideoMode(CENTER_X * 2, CENTER_Y * 2, 32, SDL_FULLSCREEN);
                  fullscreen := 1 - fullscreen;
                  break;
                end;
            end;
          end;
        end;
      SDL_MOUSEBUTTONUP:
        begin
          if (event.button.button = sdl_button_right) then
          begin
            redraw;
            SDL_UpdateRect(screen, 80, 30, 47, 95);
            break;
          end;
          if (event.button.button = sdl_button_left) then
            case menu of
              3:
                begin
                  MenuQuit;
                end;
              1:
                begin
                  MenuSave;
                end;
              0:
                begin
                  Menuload;
                end;
              2:
                begin
                  if fullscreen = 1 then
                    screen := SDL_SetVideoMode(CENTER_X * 2, CENTER_Y * 2, 32, SDL_HWSURFACE or SDL_DOUBLEBUF or SDL_ANYFORMAT)
                  else
                    screen := SDL_SetVideoMode(CENTER_X * 2, CENTER_Y * 2, 32, SDL_FULLSCREEN);
                  fullscreen := 1 - fullscreen;
                  break;
                end;
            end;
        end;
      SDL_MOUSEMOTION:
        begin
          if (event.button.x >= 80) and (event.button.x < 127) and (event.button.y > 47) and (event.button.y < 120) then
          begin
            menup := menu;
            menu := (event.button.y - 32) div 22;
            if menu > 3 then
              menu := 3;
            if menu < 0 then
              menu := 0;
            if menup <> menu then
              showMenusystem(menu);
          end;
        end;
    end;
  end;

end;

//显示系统选单

procedure ShowMenuSystem(menu: integer);
var
  word: array[0..3] of Widestring;
  i: integer;
begin
  Word[0] := ' 讀取';
  Word[1] := ' 存檔';
  Word[2] := ' 全屏';
  Word[3] := ' 離開';
  if fullscreen = 1 then
    Word[2] := ' 窗口';
  ReDraw;
  DrawRectangle(80, 30, 46, 92, 0, colcolor(255), 30);
  for i := 0 to 3 do
    if i = menu then
    begin
      drawtext(screen, @word[i][1], 64, 32 + 22 * i, colcolor($64));
      drawtext(screen, @word[i][1], 63, 32 + 22 * i, colcolor($66));
    end
    else
    begin
      drawtext(screen, @word[i][1], 64, 32 + 22 * i, colcolor($5));
      drawtext(screen, @word[i][1], 63, 32 + 22 * i, colcolor($7));
    end;
  SDL_UpdateRect(screen, 80, 30, 47, 93);

end;

//读档选单

procedure MenuLoad;
var
  menu: integer;
begin
  setlength(menustring, 6);
  setlength(Menuengstring, 0);
  menustring[0] := ' 進度一';
  menustring[1] := ' 進度二';
  menustring[2] := ' 進度三';
  menustring[3] := ' 進度四';
  menustring[4] := ' 進度五';
  menustring[5] := ' 自動檔';
  menu := commonmenu(133, 30, 67, 5);
  if menu >= 0 then
  begin
    LoadR(menu + 1);
    Redraw;
    sdl_updaterect(screen, 0, 0, screen.w, screen.h);
    ShowMenu(5);
    ShowMenusystem(0);
  end;

end;

//特殊的读档选单, 仅用在开始时读档

procedure MenuLoadAtBeginning;
var
  menu: integer;
begin
  Redraw;
  sdl_updaterect(screen, 0, 0, screen.w, screen.h);
  setlength(menustring, 6);
  setlength(Menuengstring, 0);
  menustring[0] := ' 載入進度一';
  menustring[1] := ' 載入進度二';
  menustring[2] := ' 載入進度三';
  menustring[3] := ' 載入進度四';
  menustring[4] := ' 載入進度五';
  menustring[5] := ' 載入自動檔';
  menu := commonmenu(275, 250, 107, 5);
  if menu >= 0 then
  begin
    LoadR(menu + 1);
    where := 0;
    Redraw;
    sdl_updaterect(screen, 0, 0, screen.w, screen.h);
  end;

end;

//存档选单

procedure MenuSave;
var
  menu: integer;
begin
  setlength(menustring, 5);
  menustring[0] := ' 進度一';
  menustring[1] := ' 進度二';
  menustring[2] := ' 進度三';
  menustring[3] := ' 進度四';
  menustring[4] := ' 進度五';
  menu := commonmenu(133, 30, 67, 4);
  if menu >= 0 then
    SaveR(menu + 1);

end;

//退出选单

procedure MenuQuit;
var
  menu: integer;
  str1, str2: string;
  str: widestring;
begin
  setlength(menustring, 3);
  menustring[0] := ' 取消';
  menustring[1] := ' 確定';
  menustring[2] := ' test';
  menu := commonmenu(133, 30, 45, 2);
  if menu = 1 then
  begin
    Quit;
  end;

  if menu = 2 then
  begin
    str := '  Script fail!';
    str1 := '';
    str1 := inputbox('Script file number:', str1, '1');
    str2 := '';
    str2 := inputbox('Function name:', str2, 'f1');
    if execscript(pchar('script\'+ str1 + '.lua'), pchar(str2)) <> 0 then
    begin
      DrawTextWithRect(@str[1], 100, 200, 150, $FFFFFF, $FFFFFF);
      waitanykey;
    end;
    ShowMenu(5);
    ShowMenusystem(3);
  end;

end;

//医疗的效果
//未添加体力的需求与消耗

procedure EffectMedcine(role1, role2: integer);
var
  word: widestring;
  addlife: integer;
begin
  addlife := Rrole[role1].Medcine * (10 - Rrole[role2].Hurt div 15) div 10;
  if Rrole[role2].Hurt - Rrole[role1].Medcine > 20 then
    addlife := 0;
  Rrole[role2].Hurt := Rrole[role2].Hurt - addlife div LIFE_HURT;
  if RRole[role2].Hurt < 0 then
    RRole[role2].Hurt := 0;
  if addlife > RRole[role2].MaxHP - Rrole[role2].CurrentHP then
    addlife := RRole[role2].MaxHP - Rrole[role2].CurrentHP;
  Rrole[role2].CurrentHP := Rrole[role2].CurrentHP + addlife;
  DrawRectangle(115, 98, 145, 51, 0, colcolor(255), 30);
  word := ' 增加生命';
  drawshadowtext(@word[1], 100, 125, colcolor($7), colcolor($5));
  drawbig5shadowtext(@rrole[role2].Name, 100, 100, colcolor($23), colcolor($21));
  word := format('%3d', [addlife]);
  drawengshadowtext(@word[1], 220, 125, colcolor($66), colcolor($64));
  sdl_updaterect(screen, 0, 0, screen.w, screen.h);
  waitanykey;
  redraw;

end;

//解毒的效果

procedure EffectMedPoision(role1, role2: integer);
var
  word: widestring;
  minuspoi: integer;
begin
  minuspoi := Rrole[role1].MedPoi;
  if minuspoi > Rrole[role2].Poision then
    minuspoi := Rrole[role2].Poision;
  Rrole[role2].Poision := Rrole[role2].Poision - minuspoi;
  DrawRectangle(115, 98, 145, 51, 0, colcolor(255), 30);
  word := ' 中毒減少';
  drawshadowtext(@word[1], 100, 125, colcolor($7), colcolor($5));
  drawbig5shadowtext(@rrole[role2].Name, 100, 100, colcolor($23), colcolor($21));
  word := format('%3d', [minuspoi]);
  drawengshadowtext(@word[1], 220, 125, colcolor($66), colcolor($64));
  sdl_updaterect(screen, 0, 0, screen.w, screen.h);
  waitanykey;
  redraw;

end;

//使用物品的效果
//练成秘笈的效果

procedure EatOneItem(rnum, inum: integer);
var
  i, p, l, x, y: integer;
  word: array[0..23] of widestring;
  addvalue, rolelist: array[0..23] of integer;
  str: widestring;
begin

  word[0] := ' 增加生命';
  word[1] := ' 增加生命最大值';
  word[2] := ' 中毒程度';
  word[3] := ' 增加體力';
  word[4] := ' 內力門路陰陽合一';
  word[5] := ' 增加內力';
  word[6] := ' 增加內力最大值';
  word[7] := ' 增加攻擊力';
  word[8] := ' 增加輕功';
  word[9] := ' 增加防禦力';
  word[10] := ' 增加醫療能力';
  word[11] := ' 增加用毒能力';
  word[12] := ' 增加解毒能力';
  word[13] := ' 增加抗毒能力';
  word[14] := ' 增加拳掌能力';
  word[15] := ' 增加御劍能力';
  word[16] := ' 增加耍刀能力';
  word[17] := ' 增加特殊兵器';
  word[18] := ' 增加暗器技巧';
  word[19] := ' 增加武學常識';
  word[20] := ' 增加品德指數';
  word[21] := ' 習得左右互搏';
  word[22] := ' 增加攻擊帶毒';
  word[23] := ' 受傷程度';
  rolelist[0] := 17;
  rolelist[1] := 18;
  rolelist[2] := 20;
  rolelist[3] := 21;
  rolelist[4] := 40;
  rolelist[5] := 41;
  rolelist[6] := 42;
  rolelist[7] := 43;
  rolelist[8] := 44;
  rolelist[9] := 45;
  rolelist[10] := 46;
  rolelist[11] := 47;
  rolelist[12] := 48;
  rolelist[13] := 49;
  rolelist[14] := 50;
  rolelist[15] := 51;
  rolelist[16] := 52;
  rolelist[17] := 53;
  rolelist[18] := 54;
  rolelist[19] := 55;
  rolelist[20] := 56;
  rolelist[21] := 58;
  rolelist[22] := 57;
  rolelist[23] := 19;
  //rolelist:=(17,18,20,21,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,58,57);
  for i := 0 to 22 do
  begin
    addvalue[i] := Ritem[inum].data[45 + i];
  end;
  //减少受伤
  addvalue[23] := -(addvalue[0] div LIFE_HURT);

  if - addvalue[23] > rrole[rnum].data[19] then
    addvalue[23] := -rrole[rnum].data[19];

  //增加生命, 内力最大值的处理
  if addvalue[1] + rrole[rnum].data[18] > MAX_HP then
    addvalue[1] := MAX_HP - rrole[rnum].data[18];
  if addvalue[6] + rrole[rnum].data[42] > MAX_MP then
    addvalue[6] := MAX_MP - rrole[rnum].data[42];
  if addvalue[1] + rrole[rnum].data[18] < 0 then
    addvalue[1] := -rrole[rnum].data[18];
  if addvalue[6] + rrole[rnum].data[42] < 0 then
    addvalue[6] := -rrole[rnum].data[42];

  for i := 7 to 22 do
  begin
    if addvalue[i] + rrole[rnum].data[rolelist[i]] > maxprolist[rolelist[i]] then
      addvalue[i] := maxprolist[rolelist[i]] - rrole[rnum].data[rolelist[i]];
    if addvalue[i] + rrole[rnum].data[rolelist[i]] < 0 then
      addvalue[i] := -rrole[rnum].data[rolelist[i]];
  end;
  //生命不能超过最大值
  if addvalue[0] + rrole[rnum].data[17] > addvalue[1] + rrole[rnum].data[18] then
    addvalue[0] := addvalue[1] + rrole[rnum].data[18] - rrole[rnum].data[17];
  //中毒不能小于0
  if addvalue[2] + rrole[rnum].data[20] < 0 then
    addvalue[2] := -rrole[rnum].data[20];
  //体力不能超过100
  if addvalue[3] + rrole[rnum].data[21] > MAX_PHYSICAL_POWER then
    addvalue[3] := MAX_PHYSICAL_POWER - rrole[rnum].data[21];
  //内力不能超过最大值
  if addvalue[5] + rrole[rnum].data[41] > addvalue[6] + rrole[rnum].data[42] then
    addvalue[5] := addvalue[6] + rrole[rnum].data[42] - rrole[rnum].data[41];
  p := 0;
  for i := 0 to 23 do
  begin
    if (i <> 4) and (i <> 21) and (addvalue[i] <> 0) then
      p := p + 1;
  end;
  if (addvalue[4] = 2) and (rrole[rnum].data[40] <> 2) then
    p := p + 1;
  if (addvalue[21] = 1) and (rrole[rnum].data[58] <> 1) then
    p := p + 1;

  ShowSimpleStatus(rnum, 350, 50);
  DrawRectangle(100, 70, 200, 25, 0, colcolor(255), 25);
  str := ' 服用';
  if Ritem[inum].ItemType = 2 then
    str := ' 練成';
  Drawshadowtext(@str[1], 83, 72, colcolor($23), colcolor($21));
  Drawbig5shadowtext(@Ritem[inum].Name, 143, 72, colcolor($66), colcolor($64));

  //如果增加的项超过11个, 分两列显示
  if p < 11 then
  begin
    l := p;
    Drawrectangle(100, 100, 200, 22 * l + 25, 0, colcolor($FF), 25);
  end
  else
  begin
    l := p div 2 + 1;
    Drawrectangle(100, 100, 400, 22 * l + 25, 0, colcolor($FF), 25);
  end;
  drawbig5shadowtext(@rrole[rnum].data[4], 83, 102, colcolor($23), colcolor($21));
  str := ' 未增加屬性';
  if p = 0 then
    drawshadowtext(@str[1], 163, 102, colcolor(7), colcolor(5));
  p := 0;
  for i := 0 to 23 do
  begin
    if p < l then
    begin
      x := 0;
      y := 0;
    end
    else
    begin
      x := 200;
      y := -l * 22;
    end;
    if (i <> 4) and (i <> 21) and (addvalue[i] <> 0) then
    begin
      rrole[rnum].data[rolelist[i]] := rrole[rnum].data[rolelist[i]] + addvalue[i];
      drawshadowtext(@word[i, 1], 83 + x, 124 + y + p * 22, colcolor(7), colcolor(5));
      str := format('%4d', [addvalue[i]]);
      drawengshadowtext(@str[1], 243 + x, 124 + y + p * 22, colcolor($66), colcolor($64));
      p := p + 1;
    end;
    //对内力性质特殊处理
    if (i = 4) and (addvalue[i] = 2) then
    begin
      if rrole[rnum].data[rolelist[i]] <> 2 then
      begin
        rrole[rnum].data[rolelist[i]] := 2;
        drawshadowtext(@word[i, 1], 83 + x, 124 + y + p * 22, colcolor(7), colcolor(5));
        p := p + 1;
      end;
    end;
    //对左右互搏特殊处理
    if (i = 21) and (addvalue[i] = 1) then
    begin
      if rrole[rnum].data[rolelist[i]] <> 1 then
      begin
        rrole[rnum].data[rolelist[i]] := 1;
        drawshadowtext(@word[i, 1], 83 + x, 124 + y + p * 22, colcolor(7), colcolor(5));
        p := p + 1;
      end;
    end;
  end;
  sdl_updaterect(screen, 0, 0, screen.w, screen.h);

end;

//Event.
//事件系统

procedure CallEvent(num: integer);
var
  e: array of smallint;
  i, idx, grp, offset, length, p: integer;
  check: boolean;
begin
  //CurEvent:=num;
  Cx := Sx;
  Cy := Sy;
  Sstep := 1;
  //SDL_EnableKeyRepeat(0, 10);
  idx := fileopen('resource\kdef.idx', fmopenread);
  grp := fileopen('resource\kdef.grp', fmopenread);
  if num = 0 then
  begin
    offset := 0;
    fileread(idx, length, 4);
  end
  else
  begin
    fileseek(idx, (num - 1) * 4, 0);
    fileread(idx, offset, 4);
    fileread(idx, length, 4);
  end;
  length := (length - offset) div 2;
  setlength(e, length + 1);
  fileseek(grp, offset, 0);
  fileread(grp, e[0], length * 2);
  fileclose(idx);
  fileclose(grp);
  i := 0;
  //普通事件写成子程, 需跳转事件写成函数
  while e[i] >= 0 do
  begin
    //SDL_EnableKeyRepeat(0, 10);
    case e[i] of
      0:
        begin
          i := i + 1;
          instruct_0;
          continue;
        end;
      1:
        begin
          instruct_1(e[i + 1], e[i + 2], e[i + 3]);
          i := i + 4;
        end;
      2:
        begin
          instruct_2(e[i + 1], e[i + 2]);
          i := i + 3;
        end;
      3:
        begin
          instruct_3([e[i + 1], e[i + 2], e[i + 3], e[i + 4], e[i + 5], e[i + 6], e[i + 7], e[i + 8], e[i + 9], e[i + 10], e[i + 11], e[i + 12], e[i + 13]]);
          i := i + 14;
        end;
      4:
        begin
          i := i + instruct_4(e[i + 1], e[i + 2], e[i + 3]);
          i := i + 4;
        end;
      5:
        begin
          i := i + instruct_5(e[i + 1], e[i + 2]);
          i := i + 3;
        end;
      6:
        begin
          i := i + instruct_6(e[i + 1], e[i + 2], e[i + 3], e[i + 4]);
          i := i + 5;
        end;
      7: //Break the event.
        begin
          i := i + 1;
          break;
        end;
      8:
        begin
          instruct_8(e[i + 1]);
          i := i + 2;
        end;
      9:
        begin
          i := i + instruct_9(e[i + 1], e[i + 2]);
          i := i + 3;
        end;
      10:
        begin
          instruct_10(e[i + 1]);
          i := i + 2;
        end;
      11:
        begin
          i := i + instruct_11(e[i + 1], e[i + 2]);
          i := i + 3;
        end;
      12:
        begin
          instruct_12;
          i := i + 1;
        end;
      13:
        begin
          instruct_13;
          i := i + 1;
        end;
      14:
        begin
          instruct_14;
          i := i + 1;
        end;
      15:
        begin
          instruct_15;
          i := i + 1;
          break;
        end;
      16:
        begin
          i := i + instruct_16(e[i + 1], e[i + 2], e[i + 3]);
          i := i + 4;
        end;
      17:
        begin
          instruct_17([e[i + 1], e[i + 2], e[i + 3], e[i + 4], e[i + 5]]);
          i := i + 6;
        end;
      18:
        begin
          i := i + instruct_18(e[i + 1], e[i + 2], e[i + 3]);
          i := i + 4;
        end;
      19:
        begin
          instruct_19(e[i + 1], e[i + 2]);
          i := i + 3;
        end;
      20:
        begin
          i := i + instruct_20(e[i + 1], e[i + 2]);
          i := i + 3;
        end;
      21:
        begin
          instruct_21(e[i + 1]);
          i := i + 2;
        end;
      22:
        begin
          instruct_22;
          i := i + 1;
        end;
      23:
        begin
          instruct_23(e[i + 1], e[i + 2]);
          i := i + 3;
        end;
      24:
        begin
          instruct_24;
          i := i + 1;
        end;
      25:
        begin
          instruct_25(e[i + 1], e[i + 2], e[i + 3], e[i + 4]);
          i := i + 5;
        end;
      26:
        begin
          instruct_26(e[i + 1], e[i + 2], e[i + 3], e[i + 4], e[i + 5]);
          i := i + 6;
        end;
      27:
        begin
          instruct_27(e[i + 1], e[i + 2], e[i + 3]);
          i := i + 4;
        end;
      28:
        begin
          i := i + instruct_28(e[i + 1], e[i + 2], e[i + 3], e[i + 4], e[i + 5]);
          i := i + 6;
        end;
      29:
        begin
          i := i + instruct_29(e[i + 1], e[i + 2], e[i + 3], e[i + 4], e[i + 5]);
          i := i + 6;
        end;
      30:
        begin
          instruct_30(e[i + 1], e[i + 2], e[i + 3], e[i + 4]);
          i := i + 5;
        end;
      31:
        begin
          i := i + instruct_31(e[i + 1], e[i + 2], e[i + 3]);
          i := i + 4;
        end;
      32:
        begin
          instruct_32(e[i + 1], e[i + 2]);
          i := i + 3;
        end;
      33:
        begin
          instruct_33(e[i + 1], e[i + 2], e[i + 3]);
          i := i + 4;
        end;
      34:
        begin
          instruct_34(e[i + 1], e[i + 2]);
          i := i + 3;
        end;
      35:
        begin
          instruct_35(e[i + 1], e[i + 2], e[i + 3], e[i + 4]);
          i := i + 5;
        end;
      36:
        begin
          i := i + instruct_36(e[i + 1], e[i + 2], e[i + 3]);
          i := i + 4;
        end;
      37:
        begin
          instruct_37(e[i + 1]);
          i := i + 2;
        end;
      38:
        begin
          instruct_38(e[i + 1], e[i + 2], e[i + 3], e[i + 4]);
          i := i + 5;
        end;
      39:
        begin
          instruct_39(e[i + 1]);
          i := i + 2;
        end;
      40:
        begin
          instruct_40(e[i + 1]);
          i := i + 2;
        end;
      41:
        begin
          instruct_41(e[i + 1], e[i + 2], e[i + 3]);
          i := i + 4;
        end;
      42:
        begin
          i := i + instruct_42(e[i + 1], e[i + 2]);
          i := i + 3;
        end;
      43:
        begin
          i := i + instruct_43(e[i + 1], e[i + 2], e[i + 3]);
          i := i + 4;
        end;
      44:
        begin
          instruct_44(e[i + 1], e[i + 2], e[i + 3], e[i + 4], e[i + 5], e[i + 6]);
          i := i + 7;
        end;
      45:
        begin
          instruct_45(e[i + 1], e[i + 2]);
          i := i + 3;
        end;
      46:
        begin
          instruct_46(e[i + 1], e[i + 2]);
          i := i + 3;
        end;
      47:
        begin
          instruct_47(e[i + 1], e[i + 2]);
          i := i + 3;
        end;
      48:
        begin
          instruct_48(e[i + 1], e[i + 2]);
          i := i + 3;
        end;
      49:
        begin
          instruct_49(e[i + 1], e[i + 2]);
          i := i + 3;
        end;
      50:
        begin
          p := instruct_50([e[i + 1], e[i + 2], e[i + 3], e[i + 4], e[i + 5], e[i + 6], e[i + 7]]);
          i := i + 8;
          if p < 622592 then
            i := i + p
          else
            e[i + ((p + 32768) div 655360) - 1] := p mod 655360;
        end;
      51:
        begin
          instruct_51;
          i := i + 1;
        end;
      52:
        begin
          instruct_52;
          i := i + 1;
        end;
      53:
        begin
          instruct_53;
          i := i + 1;
        end;
      54:
        begin
          instruct_54;
          i := i + 1;
        end;
      55:
        begin
          i := i + instruct_55(e[i + 1], e[i + 2], e[i + 3], e[i + 4]);
          i := i + 5;
        end;
      56:
        begin
          instruct_56(e[i + 1]);
          i := i + 2;
        end;
      57:
        begin
          i := i + 1;
        end;
      58:
        begin
          instruct_58;
          i := i + 1;
        end;
      59:
        begin
          instruct_59;
          i := i + 1;
        end;
      60:
        begin
          i := i + instruct_60(e[i + 1], e[i + 2], e[i + 3], e[i + 4], e[i + 5]);
          i := i + 6;
        end;
      61:
        begin
          i := i + e[i + 1];
          i := i + 3;
        end;
      62:
        begin
          instruct_62;
          i := i + 1;
          break;
        end;
      63:
        begin
          instruct_63(e[i + 1], e[i + 2]);
          i := i + 3;
        end;
      64:
        begin
          instruct_64;
          i := i + 1;
        end;
      65:
        begin
          i := i + 1;
        end;
      66:
        begin
          instruct_66(e[i + 1]);
          i := i + 2;
        end;
      67:
        begin
          instruct_67(e[i + 1]);
          i := i + 2;
        end;
    end;
  end;

  event.key.keysym.sym := 0;
  event.button.button := 0;

  InitialScence;
  //if where <> 2 then CurEvent := -1;
  redraw;
  sdl_updaterect(screen, 0, 0, screen.w, screen.h);
  SDL_EnableKeyRepeat(50, 30);

end;

end.

