reactOnActor

Дополнения к OpenKore, расширяющиее её функциональность, называются плагинами.

Модератор: 4epT

Аватара пользователя
Kissa2k
Профессионал
Сообщения: 1304
Зарегистрирован: Пн дек 04, 2006 8:33 pm

reactOnActor

Сообщение Kissa2k »

reactOnActor портирован на 2.1!
Кроме того теперь у него есть новая опция timeout, которая не дает блоку вызваться еще раз, если не истек таймер.
Много чего не тестировалось в полном объеме и требует доработки/переработки, поэтому пожалуйста, если найдете баги - пишите.
Скачать:
reactOnActor.zip
(2.22 КБ) 126 скачиваний
Настройки плагина в config.txt:
  • reactOnActor (command)
    This option specifies the command to use if all conditions are met for this block. Special keywords can be used on the specified commands (see below)

    Block conditions:
    • timeout (seconds)
      - specifies the minimum time to wait before reacting again.
    Actor conditions:
    • actor_id (list of numbers)
    • actor_type (player|monster|pet|npc|portal)
    • actor_whenStatusActive (list of status names)
    • actor_whenStatusInactive (list of status names)
    • actor_name (list of names)
    • actor_notName (list of names)
      Note: name and notName may not work well for players and npcs. It is still experimental. I have this assumption that it will work, but not instantly. This however will NEVER work on portals.
    • actor_lvl (range)
    • actor_x (range)
    • actor_y (range)
    • actor_dist (range)
    • actor_walkSpeed (range)
    Player conditions:
    Note: The following conditions will only work if the actor is a player.
    • actor_isJob (list of job classes)
    • actor_isNotJob (list of job classes)
    • actor_isGuild (list of guild names)
    • actor_isNotGuild (list of guild names)
    • actor_isParty (list of party names)
    • actor_isNotParty (list of party names)
      Note: isGuild, isNotGuild, isParty, and isNotParty may not work well. It is still experimental. I have this assumption that it will work, but not instantly.
    • actor_topHead (list of headgears)
    • actor_midHead (list of headgears)
    • actor_lowHead (list of headgears)
    • actor_weapon (list of equipments)
    • actor_shield (list of equipments)
      Note: topHead, midHead, lowHead, weapon, and shield should be specified as simple item names (without the card slots)..
    • actor_sex (0|1)
      Note: For sex, use 0 for girls and 1 for boys.
    • actor_isDead (boolean flag)
    • actor_isSitting (boolean flag)
    • Shared self conditions
      This block uses the shared self conditions (see the openkore manual).

    Special command keywords:
    • $actor->{ID|binID|name|type|x|y}
      This keywords are replaced with their internal equivalent
      • IDthe packed Actor ID (use this only on eval commands)
      • binIDthe index of the actor. This can be used for commands like sp or sm (e.g. sp 28 $actor->{binID})
      • namethe name of the actor (may not properly work for players and npcs)
      • typethe type of the actor (player, monster, pet, npc, or portal)
      • x
      • x
        the x- and y-coordinates of the actor, respectively.
Пример использования:

Код: Выделить всё

reactOnActor c полечите плиз {
	actor_type player
	actor_isJob Acolyte, Priest
	actor_dist < 8
	actor_lvl > 20
	actor_isDead 0
	actor_timeout 300
	hp < 50%
	inLockOnly 1
}
Плагин:

Код: Выделить всё

# =======================
# reactOnActor
# =======================
# This plugin is licensed under the GNU GPL
# original code by hakore (hakore@users.sourceforge.net)
# ported to 2.1 by Kissa2k

package reactOnActor;

use strict;
use Plugins;
use Globals;
use Utils;
use Commands;
use Misc;
use Log qw(message debug);

my @timers;

Plugins::register('reactOnActor', 'automatically react on certain actors', \&Unload, \&Unload);

my $hooks = Plugins::addHooks(
				['packet/actor_display', \&onActorDisplay, undef],
				['packet/actor_exists', \&onActorDisplay, undef],
				['packet/actor_connected', \&onActorDisplay, undef],
				['packet/actor_moved', \&onActorDisplay, undef],
				['packet/actor_spawned', \&onActorDisplay, undef]);

sub Unload {
	Plugins::delHooks($hooks);
};

sub onActorDisplay {
	my ($self, $args) = @_;
	
	my $ID = unpack("V1", $args->{ID});

	my $useActorList = (substr($Settings::VERSION, 4) >= 1);

	my $type;
	my $actor;
	if ($jobs_lut{$args->{type}}) {
		# Actor is a player
		$type = 'player';
		$actor = ($useActorList) ? $Globals::playersList->getByID($args->{ID}) : $Globals::players{$args->{ID}};

	} elsif ($args->{type} == 45) {
		# Actor is a portal
		$type = 'portal';
		$actor = ($useActorList) ? $Globals::portalsList->getByID($args->{ID}) : $Globals::portals{$args->{ID}};

	} elsif ($args->{type} >= 1000) {
		# Actor might be a monster
		if (($args->{hair_style} == 0x64) || $args->{pet}) {
			# Actor is a pet or a homunculus
			$type = 'pet';
			$actor = ($useActorList) ? $Globals::petsList->getByID($args->{ID}) : $Globals::pets{$args->{ID}};

		} else {
			# Actor really is a monster
			$type = 'monster';
			$actor = ($useActorList) ? $Globals::monstersList->getByID($args->{ID}) : $Globals::monsters{$args->{ID}};
		}

	} else {	# ($args->{type} < 1000 && $args->{type} != 45 && !$jobs_lut{$args->{type}})
		# Actor is an NPC
		$type = 'npc';
		$actor = ($useActorList) ? $Globals::npcsList->getByID($args->{ID}) : $Globals::npcs{$args->{ID}};
	}
	
	# v.1.9.0 doesn't have complete actor info
	$actor->{lv} = $args->{lv} if (!$actor->{lv} && $args->{lv});
	
	my $i = 0;
	while ((exists $config{"reactOnActor_$i"}) && $actor) {
		debug "[reactOnActor] > Checking reactOnActor_$i block...\n", "reactOnActor";
		if (
			(my $cmd = $config{"reactOnActor_$i"})
			&& main::checkSelfCondition("reactOnActor_$i")
			&& checkActorCondition("reactOnActor_${i}_actor", $actor, $type, $i)
			&& checkTimeout("reactOnActor_${i}_actor", $i)
		) {
			debug "[reactOnActor] > Check successful.\n", "reactOnActor";
			my %replace;
			$replace{ID} = $actor->{ID};
			$replace{binID} = $actor->{binID};
			$replace{name} = $actor->{name};
			$replace{type} = $type;
			my $pos = $actor->position();
			$replace{x} = $pos->{x};
			$replace{y} = $pos->{y};
			$replace{'$'} = '$';
			$cmd =~ s/\$(?:(\$)|actor->{(ID|binID|name|type|x|y)})/$replace{$1}$replace{$2}/g;
			message "[reactOnActor] Reacting to Actor ($ID) using command \"$cmd\".\n", "success";
			Commands::run($cmd);
			last;
		} else {
			debug "[reactOnActor] > Check failed.\n", "reactOnActor";
		}
		$i++;
	}
}

sub checkTimeout {
	my ($prefix, $i) = @_;
	
	return 1 unless $config{$prefix . "_timeout"};
	
	if(!$timers[$i]){
		$timers[$i] = time;
		return 1;
	}
	if(!timeOut($timers[$i], $config{$prefix . "_timeout"})){
		return 0;
	}else{
		$timers[$i] = time;
		return 1;
	}
}

sub checkActorCondition {
	my ($prefix, $actor, $type, $i) = @_;

	my $ID = unpack("V1", $actor->{ID});
	
	if ($config{$prefix . "_id"}) {
		debug "[reactOnActor] > _id " . $config{$prefix . "_id"} . " [$ID].\n", "reactOnActor";
		return 0 unless (existsInList($config{$prefix . "_id"}, $ID));
	}

	if ($config{$prefix . "_type"}) {
		debug "[reactOnActor] > _type " . $config{$prefix . "_type"} . " [$type].\n", "reactOnActor";
		return 0 unless (existsInList($config{$prefix . "_type"}, $type));
	}

	if ($actor->{walk_speed} && $config{$prefix . "_walkSpeed"}) {
		debug "[reactOnActor] > _walkSpeed " . $config{$prefix . "_walkSpeed"} . " [$actor->{walk_speed}].\n", "reactOnActor";
		return 0 unless (inRange($actor->{walk_speed}, $config{$prefix . "_walkSpeed"}));
	}

	if ($config{$prefix . "_whenStatusActive"}) {
		debug "[reactOnActor] > _whenStatusActive " . $config{$prefix . "_whenStatusActive"} . " [??].\n", "reactOnActor";
		return 0 unless (whenStatusActiveActor($actor, $config{$prefix . "_whenStatusActive"}));
	}
	
	if ($config{$prefix . "_whenStatusInactive"}) {
		debug "[reactOnActor] > _whenStatusInactive " . $config{$prefix . "_whenStatusInactive"} . " [??].\n", "reactOnActor";
		return 0 if (whenStatusActiveActor($actor, $config{$prefix . "_whenStatusInactive"}));
	}

	if ($type ne 'portal') {
		if ($config{$prefix . "_name"}) {
			debug "[reactOnActor] > _name " . $config{$prefix . "_name"} . " [$actor->{name}].\n", "reactOnActor";
			return 0 unless (existsInList($config{$prefix . "_name"}, $actor->{name}));
		}
		if ($config{$prefix . "_notName"}) {
			debug "[reactOnActor] > _notName " . $config{$prefix . "_notName"} . " [$actor->{name}].\n", "reactOnActor";
			return 0 if (existsInList($config{$prefix . "_notName"}, $actor->{name}));
		}
	}

	if ($type eq 'player') {
		if ($config{$prefix . "_isJob"}) {
			debug "[reactOnActor] > _isJob " . $config{$prefix . "_isJob"} . " [$jobs_lut{$actor->{jobID}}].\n", "reactOnActor";
			return 0 unless (existsInList($config{$prefix . "_isJob"}, $jobs_lut{$actor->{jobID}}));
		}
		if ($config{$prefix . "_isNotJob"}) {
			debug "[reactOnActor] > _isNotJob " . $config{$prefix . "_isNotJob"} . " [$jobs_lut{$actor->{jobID}}].\n", "reactOnActor";
			return 0 if (existsInList($config{$prefix . "_isNotJob"}, $jobs_lut{$actor->{jobID}}));
		}

		if ($config{$prefix."_isGuild"}) {
			debug "[reactOnActor] > _isGuild " . $config{$prefix . "_isGuild"} . " [$actor->{guild}{name}].\n", "reactOnActor";
			return 0 unless ($actor->{guild} && existsInList($config{$prefix . "_isGuild"}, $actor->{guild}{name}));
		}
		if ($config{$prefix."_isNotGuild"}) {
			debug "[reactOnActor] > _isNotGuild " . $config{$prefix . "_isNotGuild"} . " [$actor->{guild}{name}].\n", "reactOnActor";
			return 0 if ($actor->{guild} && existsInList($config{$prefix . "_isNotGuild"}, $actor->{guild}{name}));
		}

		if ($config{$prefix."_isParty"}) {
			debug "[reactOnActor] > _isParty " . $config{$prefix . "_isParty"} . " [$actor->{party}{name}].\n", "reactOnActor";
			return 0 unless ($actor->{party} && existsInList($config{$prefix . "_isParty"}, $actor->{party}{name}));
		}
		if ($config{$prefix."_isNotParty"}){
			debug "[reactOnActor] > _isNotParty " . $config{$prefix . "_isNotParty"} . " [$actor->{party}{name}].\n", "reactOnActor";
			return 0 if ($actor->{party} && existsInList($config{$prefix . "_isNotParty"}, $actor->{party}{name}));
		}

		if ($config{$prefix."_topHead"}) {
			my $item = itemNameSimple($actor->{headgear}{top});
			debug "[reactOnActor] > _topHead " . $config{$prefix . "_topHead"} . " [$item].\n", "reactOnActor";
			return 0 unless (existsInList($config{$prefix . "_topHead"}, $item));
		}
		if ($config{$prefix."_midHead"}) {
			my $item = itemNameSimple($actor->{headgear}{mid});
			debug "[reactOnActor] > _midHead " . $config{$prefix . "_midHead"} . " [$item].\n", "reactOnActor";
			return 0 unless (existsInList($config{$prefix . "_midHead"}, $item));
		}
		if ($config{$prefix."_lowHead"}) {
			my $item = itemNameSimple($actor->{headgear}{low});
			debug "[reactOnActor] > _lowHead " . $config{$prefix . "_lowHead"} . " [$item].\n", "reactOnActor";
			return 0 unless (existsInList($config{$prefix . "_lowHead"}, $item));
		}
		if ($config{$prefix."_weapon"}) {
			my $item = itemNameSimple($actor->{weapon});
			debug "[reactOnActor] > _weapon " . $config{$prefix . "_weapon"} . " [$item].\n", "reactOnActor";
			return 0 unless (existsInList($config{$prefix . "_weapon"}, $item));
		}
		if ($config{$prefix."_shield"}) {
			my $item = itemNameSimple($actor->{shield});
			debug "[reactOnActor] > _shield " . $config{$prefix . "_shield"} . " [$item].\n", "reactOnActor";
			return 0 unless (existsInList($config{$prefix . "_shield"}, $item));
		}

		if ($config{$prefix."_sex"}) {
			debug "[reactOnActor] > _sex " . $config{$prefix . "_sex"} . " [$actor->{sex}].\n", "reactOnActor";
			return 0 unless ($config{$prefix."_sex"} eq $actor->{sex});
		}

		if ($config{$prefix."_isDead"}) {
			debug "[reactOnActor] > _isDead " . $config{$prefix . "_isDead"} . " [$actor->{dead}].\n", "reactOnActor";
			return 0 unless ($actor->{dead});
		}elsif ($config{$prefix."_isSitting"}) {
			debug "[reactOnActor] > _isSitting " . $config{$prefix . "_isSitting"} . " [$actor->{sitting}].\n", "reactOnActor";
			return 0 unless ($actor->{sitting});
		}
	}

	if ($config{$prefix . "_lvl"}) {
		debug "[reactOnActor] > _lvl " . $config{$prefix . "_lvl"} . " [$actor->{lv}].\n", "reactOnActor";
		return 0 unless (inRange($actor->{lv}, $config{$prefix . "_lvl"}));
	}

	my $pos = $actor->position();
	if ($config{$prefix . "_x"}) {
		debug "[reactOnActor] > _x " . $config{$prefix . "_x"} . " [$pos->{x}].\n", "reactOnActor";
		return 0 unless (inRange($pos->{x}, $config{$prefix . "_x"}));
	}
	if ($config{$prefix . "_y"}) {
		debug "[reactOnActor] > _y " . $config{$prefix . "_y"} . " [$pos->{y}].\n", "reactOnActor";
		return 0 unless (inRange($pos->{y}, $config{$prefix . "_y"}));
	}
	if ($config{$prefix . "_dist"}) {
		my $dist = $actor->distance();
		debug "[reactOnActor] > _dist " . $config{$prefix . "_dist"} . " [$dist].\n", "reactOnActor";
		return 0 unless (inRange($dist, $config{$prefix . "_dist"}));
	}

	return $actor;
}

sub whenStatusActiveActor {
	my ($actor, $statuses) = @_;
	my @arr = split /[, ]*,[, ]*/, $statuses;
	foreach (@arr) {
		return 1 if $actor->{statuses}{$_};
	}
	return 0;
}

return 1;
Аватара пользователя
4epT
macro-маньячина
Сообщения: 2792
Зарегистрирован: Чт дек 21, 2006 1:23 pm
Сервер RO:: 4game
Discord: ya4ept#8494
Контактная информация:

Re: reactOnActor

Сообщение 4epT »

добавил в SVN под кодовым номером reactOnActor v2.1
Быстро и качественно напишу конфиг (макрос)! Стучи!
¤ Свежий бот ¤ Config checker ¤ Manual ¤
Изображение
Изображение
Ответить