Показать сообщение отдельно
Старый 29.09.2007, 22:39   #5
Пользователь
 
Регистрация: 21.09.2007
Сообщений: 37
Сказал Спасибо: 0
Имеет 10 спасибок в 2 сообщенях
Shura1oplot
По умолчанию

Работа с инвентарем
скрипт умеет добавлять и удалять вещи из инвентаря, модифицировать их свойства. знает все свойства вещей, которые знает клиент (количество, уровень заточки, надета ли вещь и пр.)
поддерживает только 80 слотов, так что под чаров, имеющих мультипрофу, надо корректировать скрипт.
Код:
var
  Inventory: array[0..79,0..9] of integer; // инвентарь (itemType1, ObjectID, ItemID, count, itemType2, CustType1, isEquipped, BodyPart, EnchantLevel, CustType2)

procedure InventoryCreate;
var
  i,k: integer;
begin
  for i:=0 to 79 do
    if (i<ReadH(4)) then begin
      Inventory[i,0]:=ReadH(i*28+6);  // itemType1
      Inventory[i,1]:=ReadD(i*28+8);  // ObjectId
      Inventory[i,2]:=ReadD(i*28+12); // ItemID
      Inventory[i,3]:=ReadD(i*28+16); // count
      Inventory[i,4]:=ReadH(i*28+20); // itemType2
      Inventory[i,5]:=ReadH(i*28+22); // CustType1
      Inventory[i,6]:=ReadH(i*28+24); // isEquipped
      Inventory[i,7]:=ReadD(i*28+26); // BodyPart
      Inventory[i,8]:=ReadH(i*28+30); // EnchantLevel
      Inventory[i,9]:=ReadH(i*28+32); // CustType2
    end else
      for k:=0 to 9 do Inventory[i,k]:=0; // забиваем нулями
end;

procedure InventoryUpdate;
var
  i,j,k: integer;
begin
  for j:=0 to (ReadH(2)-1) do begin
    case pck[j*30+4] of
      #$01: k:=0; // add item, запишет на пустую ячейку
      #$02: k:=ReadD(j*30+8); // mod item
      #$03: begin // remove item, обнулит ячейки удаленного предмета
              k:=ReadD(j*30+8);
              for i:=0 to 79 do
                if (Inventory[i,0]=k) then begin
                  for k:=0 to 9 do Inventory[i,k]:=0;
                  exit;
                end;
            end;
      end;
      for i:=0 to 79 do
        if (Inventory[i,1]=k) then begin
          Inventory[i,0]:=ReadH(j*30+6);  // itemType1
          Inventory[i,1]:=ReadD(j*30+8);  // ObjectId
          Inventory[i,2]:=ReadD(j*30+12); // ItemID
          Inventory[i,3]:=ReadD(j*30+16); // count
          Inventory[i,4]:=ReadH(j*30+20); // itemType2
          Inventory[i,5]:=ReadH(j*30+22); // CustType1
          Inventory[i,6]:=ReadH(j*30+24); // isEquipped
          Inventory[i,7]:=ReadD(j*30+26); // BodyPart
          Inventory[i,8]:=ReadH(j*30+30); // EnchantLevel
          Inventory[i,9]:=ReadH(j*30+32); // CustType2
          break;
        end;
      end;
end;

function GetInv(obj,up,down:integer): integer; // up и down не проверяются
var // 0-itemType1, 1-ObjectId, 2-ItemID, 3-count, 4-itemType2, 5-CustType1, 6-isEquipped, 7-BodyPart, 8-EnchantLevel, 9-CustType2
  i: integer;
begin
  for i:=0 to 79 do
    if (Inventory[i,up]=obj) then begin
      Result:=Inventory[i,down];
      exit;
    end;
  Result:=-1;
end;

BEGIN
  //--- INVENTORY BEGIN ---//
  if FromServer then case pck[1] of
    #$1B: InventoryCreate;
    #$27: InventoryUpdate;
  end;
  //--- INVENTORY END ---//
END.
Использовать так:
Код:
// 0-itemType1, 1-ObjectId, 2-ItemID, 3-count, 4-itemType2, 5-CustType1, 6-isEquipped, 7-BodyPart, 8-EnchantLevel, 9-CustType2

GetInv(по чему будем искать, номер того по чему будем искать, номер того что надо найти);

ex: GetInv(6408,2,1) - вернет ObjectID свадебного платья, если онное лежит в инвентаре, иначе вернет -1
ex2: GetInv(6408,2,8) - вернет уровень заточки первого попавшегося в инвентаре свадебного платья, если свадебного платья нет, то вернет -1
=======================
процедура использования предмета
Код:
procedure UseItem(ItemObjID,shift:integer);
begin
  buf:=#$14;
  WriteD(ItemObjID);
  WriteD(shift);
  SendToServer;
end;
Добавлено спустя 3 часа 26 минут 2 секунды:
Мониторинг статов чара (хп, мп, цп и координаты)
Код:
var
  CharObjID,MyCorX,MyCorY,MyCorZ: integer;
  MaxHP,CurHP,MaxMP,CurMP,MaxCP,CurCP: integer;
  CharName: string;

procedure InitStats;
var
  i: integer;
begin
  CharObjID:=ReadD(18);
  MyCorX:=ReadD(2);
  MyCorY:=ReadD(6);
  MyCorZ:=ReadD(10);
  i:=22;
  CharName:=ReadS(i);
  i:=i+44;
  MaxHP:=ReadD(i);
  CurHP:=ReadD(i);
  MaxMP:=ReadD(i);
  CurMP:=ReadD(i);
  i:=i+363;
  MaxCP:=ReadD(i);
  CurCP:=ReadD(i);
end;

procedure StatsUpdate;
var
  i: integer;
begin
  for i:=0 to ReadD(6)-1 do
    case pck[i*8+10] of
      #$09: CurHP:=ReadD(i*8+14);
      #$0A: MaxHP:=ReadD(i*8+14);
      #$0B: CurMP:=ReadD(i*8+14);
      #$0C: MaxMP:=ReadD(i*8+14);
      #$21: CurCP:=ReadD(i*8+14);
      #$22: MaxCP:=ReadD(i*8+14);
    end;
end;

procedure CorsUpdate;
begin
  MyCorX:=ReadD(2);
  MyCorY:=ReadD(6);
  MyCorZ:=ReadD(10);
end;

BEGIN
  //--- STATS BEGIN ---//
  if FromServer and (pck[1]=#$04) then InitStats;
  if FromServer and (pck[1]=#$0E) and (CharObjID=ReadD(2)) then StatsUpdate;
  if FromClient and (pck[1]=#$48) then CorsUpdate;
  //--- STATS END ---//
END.
соответственно
Код:
CharName - имя персонажа
MaxHP - максимальное кол-во хп
CurHP - текушее количество хп
по аналогии мп и цп
MyCorX (Y,Z) - текущие координаты (координаты берутся из пакетов ValidatePosition)
Добавлено спустя 47 минут 59 секунд:
Таймер со сквозным проходом (mod)
позволяет задавать переменную, по которой будет проверяться время
Код:
function Wait(var tick: integer;Timewait: Integer): Boolean;
// сквозная проверка без остановки скрипта (c)dmitry501
// modifed by Sh00rGo
var
  t: integer;
begin
  result:=false;
  t:=Round(Time*86400);
  if t>(tick+Timewait) then begin
    if tick>0 then result:=true;
    tick:=t;
  end;
end;
пример использования:
Код:
var
  time1,time2: integer;

procedure Init;
begin
  time1:=0;
  time2:=1;
end;

procedure SendMsg(msg:string);
begin 
  buf:=#$4A;
  WriteD(0);
  WriteD(10);
  WriteS('');
  WriteS(msg);
  SendToClient;
end;

function Wait(var tick: integer;Timewait: Integer): Boolean;
// сквозная проверка без остановки скрипта (c)dmitry501
// modifed by Sh00rGo
var
  t: integer;
begin
  result:=false;
  t:=Round(Time*86400);
  if t>(tick+Timewait) then begin
    if tick>0 then result:=true;
    tick:=t;
  end;
end;

begin
  if Wait(time1,2) then SendMsg('бу');
  if Wait(time2,10) then SendMsg('ы');
end.
в данном случае "бу" будет отсылаться раз в 2 секунды, а "ы" - раз в 10 секунд. переменные time1 и time2 вручную лучше не модифицировать.

если передаваемая переменная tick равна 0, то таймер сработает с заданной задержкой после первого вызова функции, если равна 1, то сразу.

в примере - "ы" отошлется сразу после первого вызова функции, а "бу" через 2 секунды после первого вызова функции.
Shura1oplot вне форума   Ответить с цитированием
За это сообщение Shura1oplot нажился 8 спасибками от: