Спаринг 2-х чаров на одном макросе

Предыдущая тема Следующая тема Перейти вниз

Спаринг 2-х чаров на одном макросе

Сообщение  Mazunchik в Сб Май 15, 2010 1:16 am

Program SparringUP;
{
Новая версия спарринга двух воинов. Делает:
1. автоопределение партнера по спаррингу (имя выводится в системный
журнал при запуске скрипта для визуального контроля)
2. автонахождение мешка под ногами с армами, оружием, бинтами
4. автоопределение направления, в котором стоит партнер по спаррингу
и, соответственно, вычисление точки для отхода (противоположное
направление, расстояние в 1 клетку)
5. автоопределение видов арма и на какие слои одевать, автоматическое
одевание арма, автоматическая проверка арма,
одетого на чара и одевание из мешка по мере разрушения.
6. автоматическое взятие в руки оружия, типы оружия занесены в массив
(по скиллам, порядок прокачки скиллов задается в скрипте)
7. Автоматическое переключение на прокачку следующего боевого после того,
как текущий вырастет до заданной величины (по умолчанию - 100.0)
8. Автоматический подхил чара во время сражения, переключение режимов
war/peace через глобальные переменные, отход чаров назад в случае
критического уменьшения здоровья, команды на начало/останов боя через
глобальные переменные, автодобор бинтов.
9. В случае отсутствия какого-либо ресурса скрипт приостанавливает свое действие,
отведя чара назад на один шаг (для безопасности), выдает в системный журнал
соответствующее сообщение и ожидает пока вы не добавите в его мешок
необходимые ресурсы.
10. Контроль за реконнектом, при необходимости переоткрытие мешка с ресурсами.

Настройка скрипта: проверьте только типы, все остальное скрипт сделает
сам. Не забудьте правильно заполнить массивы в функции IniMyArm - вам надо
изменять только типы на соответствующих слоях. Слои перечислены все, если
на каком-то слое ничего не надевается - там стоит $0000. Второй массив содержит
названия скиллов, макс размеры, типы оружия (скрипт сам будет перезаписывать нужную
строку в первом массиве по мере необходимости). Скиллы идут в том порядке, в каком
вы хотите их контролировать и качать.

Оружие в соответствии со скиллами находится в отдельном массиве. Двуручное
оружие не предусмотрено, все оружие надевается в правую руку.

Вам нет необходимости делать копии этого скрипта для каждого чара!
Один скрипт на всех чаров.


Stealth_v1.0- rc 3, (c) proZak

}


const
EnemyType1 = $0190; // типы чаров разных полов
EnemyType2 = $0191;
MyWait = 500; // пауза на перемещение и одевание
SundukType = $0E80; // Тип контейнера с армами, оружием, бинтами
Delta = 90; // Разница в здоровье с максимумом для останова
Bint= $0E21; // Бинты
HowMinBandages = 20; // Если меньше - надо, добрать
HowGetBandages = 100; // и взять вот столько


type ArmLayers = Record
typlayer : Byte; // Слой
typarm : Cardinal; // Тип вещи
end;

type DefineSkill = Record
NamSkill : String;
MaxValue : Double;
TypWeapon : Cardinal;
end;

var
MyArm : array [0..19] of ArmLayers;
MySkill : array [0..3] of DefineSkill;
EnemyWarrior, CurBag : Cardinal;
SafeX, SafeY, WarX, WarY : Integer;
LastContOpen : TDateTime;
MyFlagWar,EnemyFlagWar, CurSkill : String;
OldSkill : Double;

//******************************************
// Готовые процедцры, ниче не трогать
//******************************************
procedure CheckSave;
var Time : TDateTime;
begin
Time:= Now - (0.5 / 1440);
if InJournalBetweenTimes('Saving World State',Time,Now) >= 0 then Wait(30000)
end;

procedure WaitConnection(WaitTime : Integer);
begin
if Connected then Exit;
while not Connected do Wait(1000);
wait(WaitTime);
end;

procedure Resend;
begin
UOSay(Chr(39)+'resend');
wait(2000);
AddToSystemJournal('Соединение с сервером установлено. Окружение обновлено');
wait(6000);
end;

procedure GotoXY(x,y,prec : integer; runflag : boolean);
// x,y - координаты, в которые идем
// prec - точность подхода
// runflag - бежать или идти
// v. 1.04 (с) Edred, скрипт портирован с инжекта
// оригинальная версия Yoko с доработкой AGRS и Edred.
var ld, ldc, dx, dy, mx, my : Integer;
begin
ld := 0; ldc := 0;
while true do
begin
dx := GetX(self) - x; if dx < 0 then dx := 0 - dx;
dy := GetY(self) - y; if dy < 0 then dy := 0 - dy;
if dy > dx then dx := dy;
if dx <= prec then exit;
mx := GetX(self); my := GetY(self);
dx := mx - x; if dx < 0 then dx := 0 - dx;
dy := my - y; if dy < 0 then dy := 0 - dy;
if dy > dx then dx := dy;
if dx <= prec then exit;
if ld = dx then begin
ldc := ldc + 1;
if ldc > 100 then begin addtosystemjournal( 'GotoXY: Cannot reach location!' ); exit; end;
end
else ld := dx;
waitconnection(5000);
if mx = x then begin
if my = y then exit;
// North
if my > y then begin Raw_Move(0,runflag); continue; end;
// South
Raw_Move(4,runflag); continue;
end;
if mx < x then begin
// Northeast
if my > y then begin Raw_Move(1,runflag); continue; end;
// East
if my = y then begin Raw_Move(2,runflag); continue; end;
// Southeast
Raw_Move(3,runflag); continue;
end;
// Southwest
if my < y then begin Raw_Move(5,runflag); continue; end;
// West
if my = y then begin Raw_Move(6,runflag); continue; end;
// Nortwest
Raw_Move(7,runflag); continue;
end;
end;
//******************************************
// Основные процедуры скрипта
//******************************************
procedure IniMyArm;
begin
// Армы и оружие по слоям
MyArm[0].typlayer := RhandLayer;
MyArm[0].typarm := $0DF2;
MyArm[1].typlayer := LhandLayer;
MyArm[1].typarm := $1B74;
MyArm[2].typlayer := ShoesLayer;
MyArm[2].typarm := $0000;
MyArm[3].typlayer := PantsLayer;
MyArm[3].typarm := $13C3;
MyArm[4].typlayer := ShirtLayer;
MyArm[4].typarm := $0000;
MyArm[5].typlayer := HatLayer;
MyArm[5].typarm := $13BB;
MyArm[6].typlayer := GlovesLayer;
MyArm[6].typarm := $13F2;
MyArm[7].typlayer := RingLayer;
MyArm[7].typarm := $0000;
MyArm[8].typlayer := NeckLayer;
MyArm[8].typarm := $0000;
MyArm[9].typlayer := WaistLayer;
MyArm[9].typarm := $0000;
MyArm[10].typlayer := TorsoLayer;
MyArm[10].typarm := $13C4;
MyArm[11].typlayer := BraceLayer;
MyArm[11].typarm := $0000;
MyArm[12].typlayer := TorsoHLayer;
MyArm[12].typarm := $0000;
MyArm[13].typlayer := EarLayer;
MyArm[13].typarm := $0000;
MyArm[14].typlayer := BraceLayer;
MyArm[14].typarm := $0000;
MyArm[15].typlayer := ArmsLayer;
MyArm[15].typarm := $13EF;
MyArm[16].typlayer := CloakLayer;
MyArm[16].typarm := $0000;
MyArm[17].typlayer := RobeLayer;
MyArm[17].typarm := $0000;
MyArm[18].typlayer := EggsLayer;
MyArm[18].typarm := $0000;
MyArm[19].typlayer := LegsLayer;
MyArm[19].typarm := $0000;
// Скиллы, макс величины, оружие (для перезаписи в пред. массиве
MySkill[0].NamSkill := 'Mace Fighting';
MySkill[0].MaxValue := 100.0;
MySkill[0].TypWeapon := $0DF2; // Smith's Hammer
MySkill[1].NamSkill := 'Fencing';
MySkill[1].MaxValue := 100.0;
MySkill[1].TypWeapon := $0F51; // Dagger
MySkill[2].NamSkill := 'Swordsmanship';
MySkill[2].MaxValue := 100.0;
MySkill[2].TypWeapon := $0EC4; // Butcher's Knife
MySkill[3].NamSkill := 'Wrestling';
MySkill[3].MaxValue := 100.0;
MySkill[3].TypWeapon := $0000;
end;

function AutoFindEnemy : Cardinal;
// функция поиска чаров рядом для определения партнера по спаррингу
// Возвращает сериал партнера по спаррингу.
begin
Finddistance := 3;
Ignore(self);
if FindType(EnemyType1, Ground) = 0 then FindType(EnemyType2, Ground);
if finditem = 0 then
begin
// не нашли врагов Sad
AddToSystemJournal('Error: Партнер по спаррингу не найден!');
Result := $00000000;
Exit;
end
else
begin
// Ага! Вот он, гадина!
AddToSystemJournal('Enemy found: ' + GetName(finditem));
Result := finditem;
end;
end;

procedure OpenContainer(f : boolean);
// если f - true - просто открываем наш мешок
// если f - false - проверяем, был ли реконнект чара после последнего
// открывания контейнера, если был - переоткрываем контейнер и записываем
// новое значение в переменную LastContOpen, если не был - ничего не делаем
begin
waitconnection(3000);
if (f = true) or (LastContOpen < ConnectedTime) then
begin
Resend;
UseObject(CurBag);
wait(MyWait * 2);
checksave;
LastContOpen := Now;
addtosystemjournal('Контейнеры открыт в ' + DateTimeToStr(Now));
end;
end;

procedure CheckArm;
// проверка в цикле есть ли на соответствующих слоях нужные типы, если
// чего-то нет - возьмем это из мешка и оденем на этот слой.
VAR i : integer;
tmpid : cardinal;
begin
for i := 0 to 19 do
begin
if MyArm[i].typarm = $0000 then continue;
if GetType(ObjAtLayer(MyArm[i].typlayer)) = MyArm[i].typarm then continue;
// На соответствующем слое либо ничего не надето, либо одето что-то другое
if ObjAtLayer(MyArm[i].typlayer) <> 0 then
begin
while not UnEquip(MyArm[i].typlayer) do wait(500);
end;
// теперь на слое точно ничего не надето
waitconnection(3000);
OpenContainer(false);
if Findtype(MyArm[i].typarm,CurBag) = 0 then
begin
AddToSystemJournal('Не могу найти в мешке что надеть на слой ' + inttostr(MyArm[i].typlayer));
AddToSystemJournal('Добавьте в мешок вещь типа $' + inttohex(MyArm[i].typarm,4));
repeat
wait(MyWait * 4);
waitconnection(3000);
Findtype(MyArm[i].typarm,CurBag);
until finditem <> 0;
end;
tmpid := finditem;
while Count(MyArm[i].typarm) = 0 do
begin
waitconnection(3000);
OpenContainer(false);
Grab(tmpid,1);
wait(MyWait);
checksave;
end;
while ObjAtLayer(MyArm[i].typlayer) <> tmpid do
begin
waitconnection(3000);
Equip(MyArm[i].typlayer,tmpid);
wait(MyWait);
checksave;
end;
end;
end;

function FindEnvironment : Boolean;
// Находит под ногами у чара или сзади него мешок с добром (радиус = 3 клетка от чара)
// Возвращает false если что-то не найдено.
begin
// мешок с добром
Result := False;
WaitConnection(3000);
Resend;
Finddistance := 1;
if FindType(SundukType, Ground) = 0 then
begin
AddToSystemJournal('Error: Сундук или мешок не найден!');
exit;
end;
CurBag := finditem;
Result := True;
end;

function CreateSafePoints : boolean;
// Определяет координаты, где стоит чар и где стоит враг. Вычисляет направление
// и определяет координаты точки отхода. Записывает их в SafeX и SafeY.
// Текущие координаты - в WarX, WarY.
var tmpx, tmpy : cardinal;
begin
Result := false;
WarX := GetX(self);
WarY := GetY(self);
tmpx := GetX(EnemyWarrior);
tmpy := GetY(EnemyWarrior);
if (WarX <> tmpx) AND (WarY <> tmpY) then
begin
AddToSystemJournal('Error: Неправильная установка чаров!');
AddToSystemJournal('Чары должны стоять по одной из осей,');
AddToSystemJournal('Поставьте чаров либо по направлению 1-9 (на цифровой клавиатуре),');
AddToSystemJournal('либо по направлению 3-7.');
exit;
end;
if WarY = tmpy then
begin
SafeY := WarY;
if WarX < tmpx then SafeX := WarX - 1;
if WarX > tmpx then SafeX := WarX + 1;
if WarX = tmpx then
begin
AddToSystemJournal('Error: Чары стоят в одной точке!');
exit;
end;
end;
if WarX = tmpx then
begin
SafeX := WarX;
if WarY < tmpy then SafeY := WarY - 1;
if WarY > tmpy then SafeY := WarY + 1;
end;
Result := true;
end;

procedure CheckBandages;
// добирает из мешка, бенты (если мало)
VAR tmpid : cardinal;
i : integer;
begin
WaitConnection(3000);
if Count(Bint) >= HowMinBandages then exit;
// бинты меньше минимума
OpenContainer(false);
if FindType(Bint, CurBag) = 0 then
begin
AddToSystemjournal('Warning: Кончились бинты, подложите в мешок');
repeat
wait(MyWait * 4);
waitconnection(3000);
Findtype(Bint, CurBag);
until finditem <> 0;
end;
i := HowGetBandages;
tmpid := finditem;
if GetQuantity(tmpid) < HowGetBandages then i := GetQuantity(tmpid);
OpenContainer(false);
Grab(tmpid, i);
wait(MyWait * 2);
checksave;
end;

procedure FullHealChar;
// лечение чара до максимума
var stime : TDateTime;
i : integer;
begin
while (Life < MaxLife) do
begin
CheckBandages;
UOSay(Chr(39)+'pc heal self');
wait(7400);
i := 0;
repeat
wait(100);
i := i + 1;
until (InJournalBetweenTimes('You put the bloody bandage|failed.', stime, Now)<>-1) or (i > 300);
waitconnection(3000);
end;
end;

function SkillControl : boolean;
// Переключает какой скилл качать и перезаписывает в оружие.
// Возвращает false если необходим выход из скрипта (все вкачано).
var i : integer;
begin
waitconnection(3000);
Result := true;
for i := 0 to 3 do
begin
if GetSkillValue(MySkill[i].NamSkill) < MySkill[i].MaxValue then break;
end;
if GetSkillValue(MySkill[i].NamSkill) < MySkill[i].MaxValue then
begin
MyArm[0].typarm := MySkill[i].TypWeapon;
CurSkill := MySkill[i].NamSkill;
OldSkill := GetSkillValue(CurSkill);
end
else
begin
// Все 4-е скилла по 100.0
Result := false;
exit;
end;
end;

function EnemyHPControl : Double;
begin
Result := 100 * GetHP(EnemyWarrior) / GetMaxHP(EnemyWarrior);
end;

//******************************************
// Основная часть
//******************************************
BEGIN
waitconnection(3000);
SetGlobal('stealth',MyFlagWar,'0');
EnemyWarrior := AutoFindEnemy;
if EnemyWarrior = $00000000 then exit;
if not FindEnvironment then exit;
if not CreateSafePoints then exit;
IniMyArm;
if not SkillControl then exit;
OldSkill := GetSkillValue(CurSkill);
FullHealChar;
CheckArm;
CheckBandages;
MyFlagWar := GetName(self) + 'War';
EnemyFlagWar := GetName(EnemyWarrior) + 'War';
SetGlobal('stealth',MyFlagWar,'1');
waitconnection(3000);
repeat
wait(100);
// (Life < MaxLife) OR
until (GetGlobal('stealth',EnemyFlagWar) = '1');
// оба чара готовы к началу спарринга
while not Dead do
begin
if not WarMode then SetWarMode(true);
attack(EnemyWarrior);
repeat
if (Life < MaxLife) then
// подхил чара во время боя
begin
waitconnection(3000);
if TargetPresent then CancelTarget;
begin
UOSay(Chr(39)+'pc heal self');
wait(7400);
end;
end;
waitconnection(3000);
until (Life <= (MaxLife - Delta)) OR (GetGlobal('stealth',EnemyFlagWar) = '0') OR (EnemyHPControl < 40.0);
SetGlobal('stealth',MyFlagWar,'0');
waitconnection(3000);
GotoXY(SafeX,SafeY,0,false);
SetWarMode(false);
FullHealChar;
if GetSkillValue(CurSkill) > OldSkill then
begin
AddToSystemJournal('Скилл ' + CurSkill + ' вырос. Теперь он равен ' + FloatToStr(GetSkillValue(CurSkill)));
OldSkill := GetSkillValue(CurSkill);
if not SkillControl then exit;
end;
FullHealChar;
CheckArm;
waitconnection(3000);
GotoXY(WarX,WarY,0,false);
SetGlobal('stealth',MyFlagWar,'1');
waitconnection(3000);
repeat
wait(100);
until (Life < MaxLife) OR (GetGlobal('stealth',EnemyFlagWar) = '1');
end;
End.
avatar
Mazunchik
Admin

К-ть повідомлень : 91
Очки : 233
Дата регистрации : 2010-05-14
Возраст : 30
Звідки : СССР

Посмотреть профиль http://cccp-rip.ukrainianforum.net

Вернуться к началу Перейти вниз

Предыдущая тема Следующая тема Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения