MonsterDB plugin

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

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

Eddga
Энтузиаст
Сообщения: 88
Зарегистрирован: Ср ноя 15, 2006 3:05 am

MonsterDB plugin

Сообщение Eddga »

Сегодня напряг нашего kLabMouse что бы он поправил синтаксис плагина. За что ему большой респект. Плагин работает. Пользуемся для облегчения настроек бота.

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

############################
# MonsterDB plugin for OpenKore by Damokles
#
# This software is open source, licensed under the GNU General Public
# License, version 2.
#
# This plugin extends all functions which use 'checkMonsterCondition'.
# Basically these are AttackSkillSlot, equipAuto, AttackComboSlot, monsterSkill.
#
# Following new checks are possible:
#
# target_Element (list)
# target_notElement (list)
# target_Race (list)
# target_notRace (list)
# target_Size (list)
# target_notSize (list)
# target_hpLeft (range)
#
# In equipAuto you have to leave the target_ part,
# this is due some coding inconsistency in the funtions.pl
#
# You can use monsterEquip if you think that equipAuto is to slow.
# It supports the new equip syntax. It is event-driven and is called
# when a monster: is attacked, changes status, changes element
#
# Note: It will check all monsterEquip blocks but it respects priority.
# If you check in the first block for element fire and in the second
# for race Demi-Human and in both you use different arrows but in the
# Demi-Human block you use a bow, it will take the arrows form the first
# matching block and equip the bow since the fire block didn't specified it.
#
#
# Note: monsterEquip will modify your attackEquip_{slot} so don't be surprised
# about having other attackEquips as you set before.
#
# Be careful with right and leftHand those slots will not be checked for
# two-handed weapons that may conflict.
#
# Example:
# monsterEquip {
# 	target_Element Earth
# 	equip_arrow Fire Arrow
# }
#
# For the element names just scroll a bit down and you'll find it.
# You can check for element Lvls too, eg. target_Element Dark4
#
# $Revision: 3041 $
# $Id: monsterDB.pl 3041 2005-07-26 16:15:45Z damokles $
############################

package monsterDB;

use strict;
use Plugins;
use Globals;
use Settings;
use Log qw(message warning error debug);
use Misc qw(whenStatusActiveMon bulkConfigModify);
use Utils;


Plugins::register('monsterDB', 'extends Monster infos', \&onUnload);
my $hooks = Plugins::addHooks(
	['checkMonsterCondition', \&extendedCheck, undef],
	['packet/skill_use', \&onPacketSkillUse, undef],
	['packet/skill_use_no_damage', \&onPacketSkillUseNoDamage, undef],
	['packet/actor_action', \&onPacketAttack,undef],
	['attack_start', \&onAttackStart,undef],
	['changed_status', \&onStatusChange,undef]
);


my @monsterDB;
my @element_lut = ('Neutral','Water','Earth','Fire','Wind','Poison','Holy','Dark','Sense','Undead');
my @race_lut = ('Formless','Undead','Brute','Plant','Insect','Fish','Demon','Demi-Human','Angel','Dragon');
my @size_lut = ('Small','Medium','Large');
debug ("MonsterDB: Finished init.\n",'monsterDB',2);
loadMonDB(); # Load MonsterDB into Memory

sub onUnload {
    Plugins::delHooks($hooks);
    @monsterDB = undef;
}

sub loadMonDB {
	@monsterDB = undef;
	my @temp;
	debug ("MonsterDB: Loading DataBase\n",'monsterDB',2);
	error ("MonsterDB: cannot load $Settings::tables_folder/monsterDB.txt\n",'monsterDB',0) unless (-r "$Settings::tables_folder/monsterDB.txt");
	open MDB ,"<$Settings::tables_folder/monsterDB.txt";
	@temp = <MDB>;
	close MDB;
	my $i = 0;
	foreach my $line (@temp) {
		next unless ($line =~ /(\d{4})\s+(\d+)\s+(\d)\s+(\d)\s+(\d+)/);
		$monsterDB[(int($1) - 1000)] = [$2,$3,$4,$5];
		$i++;
	}
	message "MonsterDB: loaded $i Monsters\n",'monsterDB';
}

sub extendedCheck {
    my (undef,$args) = @_;

	return 0 if !$args->{monster} || $args->{monster}->{nameID} eq '';

	my $monsterInfo = $monsterDB[(int($args->{monster}->{nameID}) - 1000)];

    if (!defined $monsterInfo) {
    	debug("monsterDB: Monster {$args->{monster}->{name}} not found\n", 'monsterDB', 2);
    	return 0;
    } #return if monster is not in DB


    my $element = $element_lut[($monsterInfo->[3] % 10)];
    my $element_lvl = int($monsterInfo->[3] / 20);
    my $race = $race_lut[$monsterInfo->[2]];
    my $size = $size_lut[$monsterInfo->[1]];

	if ($args->{monster}->{element} && $args->{monster}->{element} ne '') {
		$element = $args->{monster}->{element};
		debug("monsterDB: Monster $args->{monster}->{name} has changed element to $args->{monster}->{element}\n", 'monsterDB', 3);
	}

	if (whenStatusActiveMon($args->{monster},'Petrified')) {
		$element = 'Earth';
		debug("monsterDB: Monster $args->{monster}->{name} is petrified changing element to Earth\n", 'monsterDB', 3);
	}

	if (whenStatusActiveMon($args->{monster},'Frozen')) {
		$element = 'Water';
		debug("monsterDB: Monster $args->{monster}->{name} is frozen changing element to Water\n", 'monsterDB', 3);
	}

    if ($config{$args->{prefix} . '_Element'}
    && (!existsInList($config{$args->{prefix} . '_Element'},$element)
    	&& !existsInList($config{$args->{prefix} . '_Element'},$element.$element_lvl))) {
		return $args->{return} = 0;
    }

    if ($config{$args->{prefix} . '_notElement'}
    && (existsInList($config{$args->{prefix} . '_notElement'},$element)
    	|| existsInList($config{$args->{prefix} . '_notElement'},$element.$element_lvl))) {
		return $args->{return} = 0;
    }

    if ($config{$args->{prefix} . '_Race'}
    && !existsInList($config{$args->{prefix} . '_Race'},$race)) {
		return $args->{return} = 0;
    }

    if ($config{$args->{prefix} . '_notRace'}
    && existsInList($config{$args->{prefix} . '_notRace'},$race)) {
		return $args->{return} = 0;
    }

    if ($config{$args->{prefix} . '_Size'}
    && !existsInList($config{$args->{prefix} . '_Size'},$size)) {
		return $args->{return} = 0;
    }

    if ($config{$args->{prefix} . '_notSize'}
    && existsInList($config{$args->{prefix} . '_notSize'},$size)) {
		return $args->{return} = 0;
    }

    if ($config{$args->{prefix} . '_hpLeft'}
    && !inRange(($monsterInfo->[0] + $args->{monster}->{deltaHp}),$config{$args->{prefix} . '_hpLeft'})) {
		return $args->{return} = 0;
    }

    return 1;
}

sub onPacketSkillUse {
	my (undef,$args) = @_;
	return 1 unless $monsters{$args->{targetID}} && $monsters{$args->{targetID}}{nameID};
	monsterHp ($monsters{$args->{targetID}});
}

sub onPacketSkillUseNoDmg {
	my (undef,$args) = @_;
	return 1 unless $monsters{$args->{targetID}} && $monsters{$args->{targetID}}{nameID};
	monsterHp ($monsters{$args->{targetID}});
	if (($args->{targetID} eq $args->{sourceID}) && ($args->{targetID} ne $accountID)){
		if ($args->{skillID} eq 'NPC_CHANGEWATER'){
			$monsters{$args->{targetID}}{element} = 'Water';
			monsterEquip($monsters{$args->{targetID}});
			return 1;
		}
		elsif ($args->{skillID} eq 'NPC_CHANGEGROUND'){
			$monsters{$args->{targetID}}{element} = 'Earth';
			monsterEquip($monsters{$args->{targetID}});
			return 1;
		}
		elsif ($args->{skillID} eq 'NPC_CHANGEFIRE'){
			$monsters{$args->{targetID}}{element} = 'Fire';
			monsterEquip($monsters{$args->{targetID}});
			return 1;
		}
		elsif ($args->{skillID} eq 'NPC_CHANGEWIND'){
			$monsters{$args->{targetID}}{element} = 'Wind';
			monsterEquip($monsters{$args->{targetID}});
			return 1;
		}
		elsif ($args->{skillID} eq 'NPC_CHANGEPOISON'){
			$monsters{$args->{targetID}}{element} = 'Poison';
			monsterEquip($monsters{$args->{targetID}});
			return 1;
		}
		elsif ($args->{skillID} eq 'NPC_CHANGEHOLY'){
			$monsters{$args->{targetID}}{element} = 'Holy';
			monsterEquip($monsters{$args->{targetID}});
			return 1;
		}
		elsif ($args->{skillID} eq 'NPC_CHANGEDARKNESS'){
			$monsters{$args->{targetID}}{element} = 'Dark';
			monsterEquip($monsters{$args->{targetID}});
			return 1;
		}
		elsif ($args->{skillID} eq 'NPC_CHANGETELEKINESIS'){
			$monsters{$args->{targetID}}{element} = 'Sense';
			monsterEquip($monsters{$args->{targetID}});
			return 1;
		}
	}
}

sub onPacketAttack {
	my (undef,$args) = @_;
	return 1 unless $args->{type} == 0 || $args->{type} > 3;
	return 1 unless $monsters{$args->{targetID}} && $monsters{$args->{targetID}}{nameID};
	monsterHp ($monsters{$args->{targetID}});

}

sub monsterHp {
	my $monster = shift;
	return 1 unless $monster && $monster->{nameID};
	my $monsterInfo = $monsterDB[(int($monster->{nameID}) - 1000)];
	message 'Monster has ['.($monsterInfo->[0] + $monster->{deltaHp}).'/'.$monsterInfo->[0]."] HP Left\n",'attackMon';
	return 1 unless defined $monsterInfo;
}

sub onAttackStart {
	my (undef,$args) = @_;
	monsterEquip($monsters{$args->{ID}});
}

sub onStatusChange {
	my (undef, $args) = @_;

	return unless $args->{changed};
	my $actor = $args->{actor};
	return unless (UNIVERSAL::isa($actor, 'Actor::Monster'));
	my $index = binFind(\@ai_seq, 'attack');
	return unless defined $index;
	return unless $ai_seq_args[$index]->{target} == $actor->{ID};
	monsterEquip($actor);
}

sub monsterEquip {
	my $monster = shift;
	return unless $monster;
	my %equip_list;

	my %args = ('monster' => $monster);
	my $slot;

	for (my $i=0;exists $config{"monsterEquip_$i"};$i++) {
		$args{prefix} = "monsterEquip_${i}_target";
		if (extendedCheck(undef,\%args)) {
			foreach $slot (%equipSlot_lut) {
				if ($config{"monsterEquip_${i}_equip_$slot"}
				&& !$equip_list{"attackEquip_$slot"}
                                && defined Actor::Item::get($config{"monsterEquip_${i}_equip_$slot"})) {				
					$equip_list{"attackEquip_$slot"} = $config{"monsterEquip_${i}_equip_$slot"};
					debug "monsterDB: using ".$config{"monsterEquip_${i}_equip_$slot"}."\n",'monsterDB';
				}
			}
		}
	}
	foreach (keys %equip_list) {
		$config{$_} = $equip_list{$_};
	}
	Actor::Item::scanConfigAndEquip('attackEquip');
}

1;
Аватара пользователя
piroJOKE
Модератор
Сообщения: 8205
Зарегистрирован: Сб ноя 04, 2006 2:20 am
Сервер RO:: localhost
Откуда: Molvania

Сообщение piroJOKE »

Хотелось бы небольшой анонс в шапке темы, вверху - на русском.
(Т.е., описание, "что это вообще такое?").

Ну и вопросы.

1)

Эти новые опции, как в том примере...

# monsterEquip {
# target_Element Earth
# equip_arrow Fire Arrow
# }

...появляются ТОЛЬКО в этом новом блоке monsterEquip, или везде?

2)

Откуда брать базу? еА?

ЗЫ: Думаю, ответы на сие - прямо в первом посте, не помешають.
Use brain against brain, ai against ai... · как правильно задавать вопросы · faq · download
skulll
Новичок
Сообщения: 9
Зарегистрирован: Пн ноя 06, 2006 11:55 pm
Контактная информация:

Сообщение skulll »

Вот проверте этот файлик вроде он.
ЗЫ Не могу сам проверить на работе... :( :(
Вложения
monsterDB.rar
(3.3 КБ) 228 скачиваний
amba
Начинающий
Сообщения: 46
Зарегистрирован: Сб окт 06, 2007 6:04 pm

Сообщение amba »

а можно как то под мага это приспособить?
и описание этого плага по подробней что где прописать надо.
Делай что можешь, случиться что должно.
Изображение
MagiicKing
Новичок
Сообщения: 13
Зарегистрирован: Вт мар 25, 2008 10:20 am

Re: MonsterDB plugin

Сообщение MagiicKing »

Кто нибудь может объяснить структуру файла monsterDB.txt?
Сущейтвующий давно не актуален, а разбираться, что значит "1001 1109 0 4 23" методом научного тыка несколько неразумно (первый ID моба, затем HP, а что означают остальные числа?)
Аватара пользователя
Cooot
Грамотный
Сообщения: 306
Зарегистрирован: Пт апр 25, 2008 8:02 am

Re: MonsterDB plugin

Сообщение Cooot »

Как раз методом научного тыка за 3 минуты выяснил, что формат такой:

ID HP Scale Race Element

Даже посмотрел некоторые значения:

Scale: 0 (small) 1 (medium) 2 (large)
Race: 0 (Formless) 1 (Undead) и т.д...
Изображение
Ответить