Forum in READ ONLY mode! All questions and discussions on Discord official server, invite link: https://discord.gg/VxsGzJ7

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

Only working scripts
Edred
Moderator
Moderator
Posts: 559
Joined: 28.03.2006 21:29

Post by Edred »

Тестируем новую версию (с армслором).

Code: Select all

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

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

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

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

 v.2.02b (c) Edred
   1.02 - вводим щиты, брать их
   1.03 - автопоиск партнера по спаррингу в радиусе 1 клетки. Ищет как
          мужиков, так и баб. Вывод в системный журнал имени найденного
          противника для визуальной проверки игрока. Автоодевание армора:
          chain туники, ног, шеи. Естественно, при необходимости добор из
          сундука.
   1.04 - Вводим подхил чаров в этот скрипт с мытьем бинтов. Стелс, как
          оказалось, очень не любит параллельно запущенных скриптов.
          Подхил идет во время боя и после останова до полного здоровья.
          Мойка для бинтов ищется вокруг чаров по типу.
   1.05 - Мелкая правка. Все равно не всегда останавливаются чары!
   2.00 - Новый алгоритм работы, смотри описание в начале скрипта
   2.01 - дополнительный контроль. Теперь чары контролируют дополнительно
          здоровье противника, если оно меньше 30% - отход на безопасные позиции.
   2.02 - Во время лечения чара в безопасной позиции теперь проверяется армор-класс
          чара. Если он меньше заданной величины - при проверке арма и оружия по слоям
          проверяется армслором износ всех вещей. Если он меньше опять же заданной
          (индивидуально для каждого типа, в массиве по слоям) величины - вещь снимается
          и сбрасывается в спецмешок для складывания битых армов (один мешок на обоих чаров),
          а чар одевает новую вещь на этот слой.
}

{$Include 'all.inc'}

const
EnemyType1 = $0190;			// типы чаров разных полов
EnemyType2 = $0191;
MyWait = 500;				// пауза на перемещение и одевание
SundukType = $0E76;			// Тип контейнера с армами, оружием, бинтами
WaterType = $B42;			// тип тазика с водой
Delta = 60;					// Разница в здоровье с максимумом для останова
Bint=$0E21;					// Бинты
BlBint=$0E20;				// Кровавые бинты
HowMinBandages = 20;		// Если меньше - вымыть и, если надо, добрать
HowGetBandages = 100;		// и взять вот столько
MinArmorClass = 50;			// Если меньше - будет проверяться битость армов
ArmorTrashType = $0E79;		// тип мешка, куда скидывать битые армы. Тип должен
							// отличаться от типа мешков с ресурсами! Мешок
							// должен лежать в доступности обоим чарам!

type ArmLayers = Record
	typlayer : Byte;		// Слой
	typarm : Cardinal;		// Тип вещи
	minarm : integer;		// минимальный допустимый уровень битости
	end;

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

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

	procedure IniMyArm;
	begin
		// Армы и оружие по слоям
		MyArm[0].typlayer := RhandLayer;
		MyArm[0].typarm := $13E3;
		MyArm[0].minarm := 1;
		MyArm[1].typlayer := LhandLayer;
		MyArm[1].typarm := $1B76;
		MyArm[1].minarm := 10;
		MyArm[2].typlayer := ShoesLayer;
		MyArm[2].typarm := $0000;
		MyArm[2].minarm := 20;
		MyArm[3].typlayer := PantsLayer;
		MyArm[3].typarm := $1411;
		MyArm[3].minarm := 20;
		MyArm[4].typlayer := ShirtLayer;
		MyArm[4].typarm := $0000;
		MyArm[4].minarm := 20;
		MyArm[5].typlayer := HatLayer;
		MyArm[5].typarm := $1412;
		MyArm[5].minarm := 20;
		MyArm[6].typlayer := GlovesLayer;
		MyArm[6].typarm := $1414;
		MyArm[6].minarm := 20;
		MyArm[7].typlayer := RingLayer;
		MyArm[7].typarm := $0000;
		MyArm[7].minarm := 20;
		MyArm[8].typlayer := NeckLayer;
		MyArm[8].typarm := $1413;
		MyArm[8].minarm := 20;
		MyArm[9].typlayer := WaistLayer;
		MyArm[9].typarm := $0000;
		MyArm[9].minarm := 20;
		MyArm[10].typlayer := TorsoLayer;
		MyArm[10].typarm := $1415;
		MyArm[10].minarm := 20;
		MyArm[11].typlayer := BraceLayer;
		MyArm[11].typarm := $0000;
		MyArm[11].minarm := 20;
		MyArm[12].typlayer := TorsoHLayer;
		MyArm[12].typarm := $0000;
		MyArm[12].minarm := 20;
		MyArm[13].typlayer := EarLayer;
		MyArm[13].typarm := $0000;
		MyArm[13].minarm := 20;
		MyArm[14].typlayer := BraceLayer;
		MyArm[14].typarm := $0000;
		MyArm[14].minarm := 20;
		MyArm[15].typlayer := ArmsLayer;
		MyArm[15].typarm := $1410;
		MyArm[15].minarm := 20;
		MyArm[16].typlayer := CloakLayer;
		MyArm[16].typarm := $0000;
		MyArm[16].minarm := 20;
		MyArm[17].typlayer := RobeLayer;
		MyArm[17].typarm := $0000;
		MyArm[17].minarm := 20;
		MyArm[18].typlayer := EggsLayer;
		MyArm[18].typarm := $0000;
		MyArm[18].minarm := 20;
		MyArm[19].typlayer := LegsLayer;
		MyArm[19].typarm := $0000;
		MyArm[19].minarm := 20;
		// Скиллы, макс величины, оружие (для перезаписи в пред. массиве
		MySkill[0].NamSkill := 'Mace Fighting';
		MySkill[0].MaxValue := 100.0;
		MySkill[0].TypWeapon := $13E3;		// 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 := $13F6;		// Butcher's Knife
	end;

	function AutoFindEnemy : Cardinal;
	// функция поиска чаров рядом для определения партнера по спаррингу
	// Возвращает сериал партнера по спаррингу.
	begin
		Finddistance := 1;
		Ignore(self);
		if FindType(EnemyType1, Ground) = 0 then FindType(EnemyType2, Ground);
		if finditem = 0 then
		begin
			// не нашли врагов :(
			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
			UseObject(CurBag);
			wait(MyWait * 2);
			checksave;
			UseObject(ArmorTrash);
			wait(MyWait * 2);
			checksave;
			LastContOpen := Now;
			addtosystemjournal('Контейнеры открыт в ' + DateTimeToStr(Now));
		end;
	end;

	function testCurArm(tlayer : byte; tmin : integer) : boolean;
	{ Тестируем вещь на указанном слое армслором.
	  ловим в журнале ответ, парсим его, вычленяем величину. Если она меньше
	  переданного значения - возвращаем true, иначе - false
	  Вот образцы строк:

	  Defense [56].This item is in full repair.
	  Defense [8].This item is badly damaged.
	  Defense [0].This item is about to fall apart.It looks quite fragile.
	  Defense [48].This item is a bit worn.
	
	  В журнале будет ловиться строка содержащая 'Defense'. Из нее вычленяться
	  число в квадратных скобках. Если на вашем шарде армслор выдает другие строки,
	  вам придется переписать эту функцию.
	}
	var tmpid : Cardinal;
		tmptime : TDateTime;
		r, p : Integer;
		tmpstr : String;
	begin
		Result :=false;
		tmpid := ObjAtLayer(tlayer);
		if TargetPresent then CancelTarget;
		tmptime := Now;
		UseSkill('Arms Lore');
		WaitForTarget(5000);
		If TargetPresent then TargetToObject(tmpid);
		r := 0;
		repeat
			wait(100);
			r := r + 1;
			p := InJournalBetweenTimes('Defense', tmptime, Now);
		until (p <> -1) or (r > 300);
		if p <> -1 then
		begin
			tmpstr := Journal(p);
			r := Pos('[',tmpstr);
			p := Pos(']',tmpstr);
			if StrToInt(Copy(tmpstr,r+1,p-r-1)) < tmin then Result := True;
		end else Addtosystemjournal('Warning: Армслор не работает. Проверьте правильность тестирования');
	end;

	procedure CheckArm;
	// проверка в цикле есть ли на соответствующих слоях нужные типы, если
	// чего-то нет - возьмем это из мешка и оденем на этот слой.
	VAR i : integer;
		tmpid : cardinal;
		testarm : boolean;
	begin
		if Armor < MinArmorClass then testarm := true else testarm := false;
		for i := 0 to 19 do
		begin
			if MyArm[i].typarm = $0000 then continue;
			if GetType(ObjAtLayer(MyArm[i].typlayer)) = MyArm[i].typarm then
			begin
				if not testarm then continue;
				// требуется проверка текущей части арма на битость
				if i = 0 then continue;
				if not testCurArm(MyArm[i].typlayer,MyArm[i].minarm) then continue;
			end;
			// На соответствующем слое либо ничего не надето, либо одето что-то другое
			if (ObjAtLayer(MyArm[i].typlayer) <> 0) then
			begin
				tmpid := ObjAtLayer(MyArm[i].typlayer);
				while not UnEquip(MyArm[i].typlayer) do wait(500);
				// тут надо сделать сброс снятой вещи в пак для битых армов
				OpenContainer(false);
				MoveItem(tmpid,1,ArmorTrash,0,0,0);
				wait(MyWait);
				checksave;
			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;
	// Находит под ногами у чара или сзади него мешок с добром (радиус = 1 клетка от чара)
	// Находит корыто с водой для мытья бинтов (радиус = 2 клетки от чара)
	// Находит мешок для битых армов (радиус = 3 клетки от чара)
	// Возвращает false если что-то не найдено.
	begin
		// мешок с добром
		Result := False;
		WaitConnection(3000);
		Finddistance := 1;
		if FindType(SundukType, Ground) = 0 then
		begin
			AddToSystemJournal('Error: Сундук или мешок не найден!');
			exit;
		end;
		CurBag := finditem;
		// мешок для битых армов
		Finddistance := 3;
		if FindType(ArmorTrashType, Ground) = 0 then
		begin
			AddToSystemJournal('Error: Сундук или мешок для битых армов не найден!');
			exit;
		end;
		ArmorTrash := finditem;
		LastContOpen := Now;
		OpenContainer(true);
		// корыто с водой
		Finddistance := 2;
		WaterID := FindType(WaterType, Ground);
		if WaterID = 0 then
		begin
			AddToSystemJournal('Error: Корыто с водой не найдено!');
			exit;
		end;
		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;
		// проверим грязные и помоем
		findtype(BlBint,backpack);
		while (FindCount > 0) do
		begin
			WaitConnection(3000);
			checksave;
			useobject(FindItem);
			waitfortarget(5000);
			if TargetPresent then TargetToObject(WaterID);
			wait(MyWait * 2);
			findtype(BlBint,backpack);
		end;
		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 (HP < MaxHP) do
		begin
			CheckBandages;
			if TargetPresent then CancelTarget;
			stime := Now;
			if UseType(Bint,$FFFF) = 0 then break;
			WaitForTarget(5000);
			If TargetPresent then TargetToObject(Self);
			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;

	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;

	function SkillControl : boolean;
	// Переключает какой скилл качать и перезаписывает в оружие.
	// Возвращает false если необходим выход из скрипта (все вкачано).
	var i : integer;
	begin
		waitconnection(3000);
		Result := true;
		for i := 0 to 2 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;
		end
		else
		begin
			// Все три скилла по 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);
	until (Life < MaxLife) OR (GetGlobal('stealth',EnemyFlagWar) = '1');
	// оба чара готовы к началу спарринга
	while not Dead do
	begin
		if not WarMode then SetWarMode(true);
		attack(EnemyWarrior);
		k := 0;
		repeat
			wait(100);
			k := k + 1;
			if (k = 50) and (count(Bint) > 0) and (Life < MaxLife) then
			// подхил чара во время боя
			begin
				waitconnection(3000);
				if TargetPresent then CancelTarget;
				if UseType(Bint,$FFFF) <> 0 then
				begin
					WaitForTarget(5000);
					If TargetPresent then TargetToObject(Self);
					k := 0;
				end;
			end;
			waitconnection(3000);
		until (Life <= (MaxLife - Delta)) OR (GetGlobal('stealth',EnemyFlagWar) = '0') OR (EnemyHPControl < 30.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;
		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.
Sadner
Posts: 1
Joined: 02.12.2006 8:45
Contact:

Post by Sadner »

Прива :) очень заинтересовался этим клиентом,но вот проблема с написанием и даже исправлением скриптов(даже на инже) :oops: не мог бы помочь этот скриптик немного подправить?там немного , прото убрать корыто с водой чтобы бинты не мыли и чтоб во время драчки анатомию юзали :D
Edred
Moderator
Moderator
Posts: 559
Joined: 28.03.2006 21:29

Post by Edred »

Без корыта с водой скрипт мог работать в старых версиях, в дальнейшем я планирую универсализацию скрипта и вновь введу такую возможность. Но только после полной отладки скрипта и добавления в него всего, что может еще потребоваться. Скрипт пока несовершенен. В частности:

1. Один чар иногда (причины не выяснены) нападает на второго в начале работы скрипта, когда второй чар еще не готов

2. Хочу изменить алгоритм смены скилла/оружия - счас меняется только после достижения скилла до указанной величины, а если оружие кончилось (этого типа) раньше - скрипт встает на паузу. Надо сделать переключение на другой скилл если есть при этом оружие другого типа.

3. Если нет никакого оружия в запасе но есть скилл Врестлинг - переключаться на драку кулаками. Тоже самое если не вкачаны парринг и тактика.

4. Думаю еще ввести таймаут на драку. То есть задавать принудительно максимальное время одной схватки до отхода на безопасные позиции. Это позволит минимизировать риски.

5. Может быть введу авторес чаров от противника или от третьего чара, стоящего недалеко. Пока не знаю буду ли такое делать. В любом случае реакцию на смерть чара предусмотреть надо. То есть выживший сбрасывает атаку и встает в точку варки и ждет. Умерший подает звуковой сигнал и снимает скрипт. Может быть так, может быть иначе. Еще не решил окончательно.

Анатомию вводить не планирую. Это особенность твоего шарда, на других я не встречал такого использования анатомии. Исправь сам, проверка специально вынесена в отдельную функцию.

В любом случае, сначала полная отладка скрипта. Я каждый вечер вношу в скрипт 2-3 мелких изменения, просто на форум кладу версии только при вводе чего-то нового. В частности, последняя опубликованная версия не скидывает из пака битые части арма. Там не хватает полсекундной паузы перед этой командой. И т. д.
Edred
Moderator
Moderator
Posts: 559
Joined: 28.03.2006 21:29

Post by Edred »

Новая версия. Ввел опциональную возможность задавать ограничение по времени каждой схватки (для отключения вводится 0). Плюс исправил кучу мелких недочетов. По пункту 1 предыдущего поста выяснил, поправил.

Code: Select all

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

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

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

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

 v.2.03b (c) Edred

   1.02 - вводим щиты, брать их
   1.03 - автопоиск партнера по спаррингу в радиусе 1 клетки. Ищет как
          мужиков, так и баб. Вывод в системный журнал имени найденного
          противника для визуальной проверки игрока. Автоодевание армора:
          chain туники, ног, шеи. Естественно, при необходимости добор из
          сундука.
   1.04 - Вводим подхил чаров в этот скрипт с мытьем бинтов. Стелс, как
          оказалось, очень не любит параллельно запущенных скриптов.
          Подхил идет во время боя и после останова до полного здоровья.
          Мойка для бинтов ищется вокруг чаров по типу.
   1.05 - Мелкая правка. Все равно не всегда останавливаются чары!
   2.00 - Новый алгоритм работы, смотри описание в начале скрипта
   2.01 - дополнительный контроль. Теперь чары контролируют дополнительно
          здоровье противника, если оно меньше 30% - отход на безопасные позиции.
   2.02 - Во время лечения чара в безопасной позиции теперь проверяется армор-класс
          чара. Если он меньше заданной величины - при проверке арма и оружия по слоям
          проверяется армслором износ всех вещей. Если он меньше опять же заданной
          (индивидуально для каждого типа, в массиве по слоям) величины - вещь снимается
          и сбрасывается в спецмешок для складывания битых армов (один мешок на обоих чаров),
          а чар одевает новую вещь на этот слой.
   2.03 - Вводим максимальное время одной схватки (от подхода с безопасных позиций до
          нового отхода на эти позиции). Это время задается в константах.
}

{$Include 'all.inc'}

const
EnemyType1 = $0190;			// типы чаров разных полов
EnemyType2 = $0191;
MyWait = 500;				// пауза на перемещение и одевание
SundukType = $0E76;			// Тип контейнера с армами, оружием, бинтами
WaterType = $B42;			// тип тазика с водой
Delta = 60;					// Разница в здоровье с максимумом для останова
Bint=$0E21;					// Бинты
BlBint=$0E20;				// Кровавые бинты
HowMinBandages = 20;		// Если меньше - вымыть и, если надо, добрать
HowGetBandages = 100;		// и взять вот столько
MinArmorClass = 50;			// Если меньше - будет проверяться битость армов
MaxWarTime = 3;				// (см. v.2.03) - в минутах, минимум 0, максимум 59.
							// 0 - означает отмену проверки по времени.
ArmorTrashType = $0E79;		// тип мешка, куда скидывать битые армы. Тип должен
							// отличаться от типа мешков с ресурсами! Мешок
							// должен лежать в доступности обоим чарам!

type ArmLayers = Record
	typlayer : Byte;		// Слой
	typarm : Cardinal;		// Тип вещи
	minarm : integer;		// минимальный допустимый уровень битости
	end;

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

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

	procedure IniMyArm;
	begin
		// Армы и оружие по слоям
		MyArm[0].typlayer := RhandLayer;
		MyArm[0].typarm := $13E3;
		MyArm[0].minarm := 1;
		MyArm[1].typlayer := LhandLayer;
		MyArm[1].typarm := $1B76;
		MyArm[1].minarm := 10;
		MyArm[2].typlayer := ShoesLayer;
		MyArm[2].typarm := $0000;
		MyArm[2].minarm := 20;
		MyArm[3].typlayer := PantsLayer;
		MyArm[3].typarm := $1411;
		MyArm[3].minarm := 20;
		MyArm[4].typlayer := ShirtLayer;
		MyArm[4].typarm := $0000;
		MyArm[4].minarm := 20;
		MyArm[5].typlayer := HatLayer;
		MyArm[5].typarm := $1412;
		MyArm[5].minarm := 20;
		MyArm[6].typlayer := GlovesLayer;
		MyArm[6].typarm := $1414;
		MyArm[6].minarm := 20;
		MyArm[7].typlayer := RingLayer;
		MyArm[7].typarm := $0000;
		MyArm[7].minarm := 20;
		MyArm[8].typlayer := NeckLayer;
		MyArm[8].typarm := $1413;
		MyArm[8].minarm := 20;
		MyArm[9].typlayer := WaistLayer;
		MyArm[9].typarm := $0000;
		MyArm[9].minarm := 20;
		MyArm[10].typlayer := TorsoLayer;
		MyArm[10].typarm := $1415;
		MyArm[10].minarm := 20;
		MyArm[11].typlayer := BraceLayer;
		MyArm[11].typarm := $0000;
		MyArm[11].minarm := 20;
		MyArm[12].typlayer := TorsoHLayer;
		MyArm[12].typarm := $0000;
		MyArm[12].minarm := 20;
		MyArm[13].typlayer := EarLayer;
		MyArm[13].typarm := $0000;
		MyArm[13].minarm := 20;
		MyArm[14].typlayer := BraceLayer;
		MyArm[14].typarm := $0000;
		MyArm[14].minarm := 20;
		MyArm[15].typlayer := ArmsLayer;
		MyArm[15].typarm := $1410;
		MyArm[15].minarm := 20;
		MyArm[16].typlayer := CloakLayer;
		MyArm[16].typarm := $0000;
		MyArm[16].minarm := 20;
		MyArm[17].typlayer := RobeLayer;
		MyArm[17].typarm := $0000;
		MyArm[17].minarm := 20;
		MyArm[18].typlayer := EggsLayer;
		MyArm[18].typarm := $0000;
		MyArm[18].minarm := 20;
		MyArm[19].typlayer := LegsLayer;
		MyArm[19].typarm := $0000;
		MyArm[19].minarm := 20;
		// Скиллы, макс величины, оружие (для перезаписи в пред. массиве
		MySkill[0].NamSkill := 'Mace Fighting';
		MySkill[0].MaxValue := 100.0;
		MySkill[0].TypWeapon := $13E3;		// 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 := $13F6;		// Butcher's Knife
	end;

	function AutoFindEnemy : Cardinal;
	// функция поиска чаров рядом для определения партнера по спаррингу
	// Возвращает сериал партнера по спаррингу.
	begin
		Finddistance := 1;
		Ignore(self);
		if FindType(EnemyType1, Ground) = 0 then FindType(EnemyType2, Ground);
		if finditem = 0 then
		begin
			// не нашли врагов :(
			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
			UseObject(CurBag);
			wait(MyWait * 2);
			checksave;
			UseObject(ArmorTrash);
			wait(MyWait * 2);
			checksave;
			LastContOpen := Now;
			addtosystemjournal('Контейнеры открыт в ' + DateTimeToStr(Now));
		end;
	end;

	function testCurArm(tlayer : byte; tmin : integer) : boolean;
	{ Тестируем вещь на указанном слое армслором.
	  ловим в журнале ответ, парсим его, вычленяем величину. Если она меньше
	  переданного значения - возвращаем true, иначе - false
	  Вот образцы строк:

	  Defense [56].This item is in full repair.
	  Defense [8].This item is badly damaged.
	  Defense [0].This item is about to fall apart.It looks quite fragile.
	  Defense [48].This item is a bit worn.
	
	  В журнале будет ловиться строка содержащая 'Defense'. Из нее вычленяться
	  число в квадратных скобках. Если на вашем шарде армслор выдает другие строки,
	  вам придется переписать эту функцию.
	}
	var tmpid : Cardinal;
		tmptime : TDateTime;
		r, p : Integer;
		tmpstr : String;
	begin
		Result :=false;
		tmpid := ObjAtLayer(tlayer);
		if TargetPresent then CancelTarget;
		tmptime := Now;
		UseSkill('Arms Lore');
		WaitForTarget(5000);
		If TargetPresent then TargetToObject(tmpid);
		r := 0;
		repeat
			wait(100);
			r := r + 1;
			p := InJournalBetweenTimes('Defense', tmptime, Now);
		until (p <> -1) or (r > 300);
		if p <> -1 then
		begin
			tmpstr := Journal(p);
			r := Pos('[',tmpstr);
			p := Pos(']',tmpstr);
			if StrToInt(Copy(tmpstr,r+1,p-r-1)) < tmin then Result := True;
		end else Addtosystemjournal('Warning: Армслор не работает. Проверьте правильность тестирования');
	end;

	procedure CheckArm;
	// проверка в цикле есть ли на соответствующих слоях нужные типы, если
	// чего-то нет - возьмем это из мешка и оденем на этот слой.
	VAR i : integer;
		tmpid : cardinal;
		testarm : boolean;
	begin
		if Armor < MinArmorClass then testarm := true else testarm := false;
		for i := 0 to 19 do
		begin
			if MyArm[i].typarm = $0000 then continue;
			if GetType(ObjAtLayer(MyArm[i].typlayer)) = MyArm[i].typarm then
			begin
				if not testarm then continue;
				// требуется проверка текущей части арма на битость
				if i = 0 then continue;
				if not testCurArm(MyArm[i].typlayer,MyArm[i].minarm) then continue;
			end;
			// На соответствующем слое либо ничего не надето, либо одето что-то другое
			if (ObjAtLayer(MyArm[i].typlayer) <> 0) then
			begin
				while not UnEquip(MyArm[i].typlayer) do wait(500);
				wait(500);
				// тут надо сделать сброс снятой вещи в пак для битых армов
				OpenContainer(false);
				if (Findtype(MyArm[i].typarm,backpack) <> 0) then
				begin
					MoveItem(finditem,GetQuantity(finditem),ArmorTrash,0,0,0);
					wait(MyWait);
					checksave;
				end;
			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;
	// Находит под ногами у чара или сзади него мешок с добром (радиус = 1 клетка от чара)
	// Находит корыто с водой для мытья бинтов (радиус = 2 клетки от чара)
	// Находит мешок для битых армов (радиус = 3 клетки от чара)
	// Возвращает false если что-то не найдено.
	begin
		// мешок с добром
		Result := False;
		WaitConnection(3000);
		Finddistance := 1;
		if FindType(SundukType, Ground) = 0 then
		begin
			AddToSystemJournal('Error: Сундук или мешок не найден!');
			exit;
		end;
		CurBag := finditem;
		// мешок для битых армов
		Finddistance := 3;
		if FindType(ArmorTrashType, Ground) = 0 then
		begin
			AddToSystemJournal('Error: Сундук или мешок для битых армов не найден!');
			exit;
		end;
		ArmorTrash := finditem;
		LastContOpen := Now;
		OpenContainer(true);
		// корыто с водой
		Finddistance := 2;
		WaterID := FindType(WaterType, Ground);
		if WaterID = 0 then
		begin
			AddToSystemJournal('Error: Корыто с водой не найдено!');
			exit;
		end;
		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;
		// проверим грязные и помоем
		findtype(BlBint,backpack);
		while (FindCount > 0) do
		begin
			WaitConnection(3000);
			checksave;
			useobject(FindItem);
			waitfortarget(5000);
			if TargetPresent then TargetToObject(WaterID);
			wait(MyWait * 2);
			findtype(BlBint,backpack);
		end;
		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 (HP < MaxHP) do
		begin
			CheckBandages;
			if TargetPresent then CancelTarget;
			stime := Now;
			if UseType(Bint,$FFFF) = 0 then break;
			WaitForTarget(5000);
			If TargetPresent then TargetToObject(Self);
			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;

	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;

	function SkillControl : boolean;
	// Переключает какой скилл качать и перезаписывает в оружие.
	// Возвращает false если необходим выход из скрипта (все вкачано).
	var i : integer;
	begin
		waitconnection(3000);
		Result := true;
		for i := 0 to 2 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
			// Все три скилла по 100.0
			Result := false;
			exit;
		end;
	end;

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

	function TestTime : boolean;
	begin
		Result := False;
		if MaxWarTime = 0 then exit;
		if (qtime + MaxTime4War) < Now then
		begin
			Result := true;
			exit;
		end;
	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;
	if (MaxWarTime > 59) OR (MaxWarTime < 0) then
	begin
		AddToSystemJournal('Error: Неправильное максимальное время схватки!');
		exit;
	end;
	MaxTime4War := EncodeTime(0,MaxWarTime,0,0);
	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);
		k := 0;
		qtime := Now;
		repeat
			wait(100);
			k := k + 1;
			if (k = 50) and (count(Bint) > 0) and (Life < MaxLife) then
			// подхил чара во время боя
			begin
				waitconnection(3000);
				if TargetPresent then CancelTarget;
				if UseType(Bint,$FFFF) <> 0 then
				begin
					WaitForTarget(5000);
					If TargetPresent then TargetToObject(Self);
					k := 0;
				end;
			end;
			waitconnection(3000);
		until (Life <= (MaxLife - Delta)) OR (GetGlobal('stealth',EnemyFlagWar) = '0') OR (EnemyHPControl < 30.0) OR (Armor < MinArmorClass) OR TestTime;
		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;
		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.
Capricorn
Posts: 2
Joined: 06.12.2006 23:39

Post by Capricorn »

собсна есть вопрос как поставить на него чаров? нужно юзать етот скрипт обоим чарам или как?
Edred
Moderator
Moderator
Posts: 559
Joined: 28.03.2006 21:29

Post by Edred »

Capricorn wrote:собсна есть вопрос как поставить на него чаров? нужно юзать етот скрипт обоим чарам или как?
Угадай с трех раз. А лучше почитай комментарии в скрипте в начале. И предыдущую страницу темы.
Fantastick
Neophyte
Neophyte
Posts: 10
Joined: 02.12.2006 20:37

Post by Fantastick »

Почему после сохранения мира чары перестают бить друг друга, они просто остаются в варе и ни чего не происходит??

ps как-то можно это исправить?
Lokkie
Neophyte
Neophyte
Posts: 30
Joined: 02.08.2006 7:55

Post by Lokkie »

Спасибо за скрипт.
Я его слегка облегчил под свой шард (напр., убрал доспехи и мытьё бинтов, хилинг под клилоки). Работает. Только ингода чар отходит подхилиться - закрываются ящики (вроде, как проверить?). А это приводит к такому зацикливанию:

Code: Select all

16:01:57 [Drovosek]: Script warning: correct pickuped item
16:02:34 [Drovosek]: Script: error drag item. drag timeout
поставил OpenContainer(true); не помогло...
:roll:
Edred
Moderator
Moderator
Posts: 559
Joined: 28.03.2006 21:29

Post by Edred »

Замени ящики мешками и положи их в те точки, куда чары отходят отхиливаться. Тогда точно закрываться не должны.
nync
Posts: 1
Joined: 19.03.2008 3:06

Post by nync »

Мужики, а не подскажете как скриптец одаптировать под Шард гдле оружие слетает вовремя хилла..и уменьшить время ожидания после выхила (полного)...

Буду презнателен...
Blaze
Neophyte
Neophyte
Posts: 13
Joined: 07.08.2008 5:33
Location: [Dark Nazguls]

Post by Blaze »

На ДРВ фишка в том, что если поставить в спарринг двух чаров с одного компьютера, то боевые не растут. Как быть в этом случае?
RaTaMaHaTTa
Novice
Novice
Posts: 89
Joined: 16.06.2008 12:22
Location: <||TORCHKI||>
Contact:

Post by RaTaMaHaTTa »

Blaze wrote:На ДРВ фишка в том, что если поставить в спарринг двух чаров с одного компьютера, то боевые не растут. Как быть в этом случае?
Трафик компресор юзать.
Blaze
Neophyte
Neophyte
Posts: 13
Joined: 07.08.2008 5:33
Location: [Dark Nazguls]

Post by Blaze »

Как сильно эта программа уменьшает трафик при игре в УО? Сам юзаешь?
Трафик компрессор позволяет менять IP адрес компьютера?
proZak
Novice
Novice
Posts: 78
Joined: 28.02.2008 0:08
Location: [Age of Power]
Contact:

Post by proZak »

Image

Почему они несходятса для боя???????? (одеваютсо с сундука вроде норм, становятсо в Вар мод, а подходить не хотят друг к другу)- при етом скрипт не вылетает, несбиваетсо все работает.
[Ultima and Dota]-pro... Gamer
RaTaMaHaTTa
Novice
Novice
Posts: 89
Joined: 16.06.2008 12:22
Location: <||TORCHKI||>
Contact:

Post by RaTaMaHaTTa »

Blaze wrote:Как сильно эта программа уменьшает трафик при игре в УО? Сам юзаешь?
Трафик компрессор позволяет менять IP адрес компьютера?
Нашет сжатия я не знаю.
Юзал пару лет назад когда пинг с дрв был за 100.
А с трафиком играл через их сервера отуда и айпи ихний.
Post Reply