Работа с инвентарем
скрипт умеет добавлять и удалять вещи из инвентаря, модифицировать их свойства. знает все свойства вещей, которые знает клиент (количество, уровень заточки, надета ли вещь и пр.)
поддерживает только 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 секунды после первого вызова функции.