Skip to content

Instantly share code, notes, and snippets.

@elvisoliveira
Created June 8, 2025 16:27
Show Gist options
  • Select an option

  • Save elvisoliveira/fed5f15f1f71824f9ae0502a269fceb4 to your computer and use it in GitHub Desktop.

Select an option

Save elvisoliveira/fed5f15f1f71824f9ae0502a269fceb4 to your computer and use it in GitHub Desktop.
# autowarpn (completely new code by Joseph)
# licensed under gpl v2
# ported to 2.x by Kissa2k
# v2 by oqhadev fix
# - Fix cast warp stuck cause cast to self cordinate
# - Fix warp not trigger cause waiting to lockMap route queue
# - add autoWarp config Init (to lazy to edit config one by one if you have multiple bot, so just run this command via bus)
# - add condition move to warp only trigger on queue autowarp active
# - Fix trigger without gemstone, now autowarp only trigger if you had blue gemstone
package autowarpn;
use strict;
use Globals;
use Log qw(message);
use Utils;
use Network::Send;
use Misc;
use AI;
Plugins::register('autowarpn', 'Auto warp before walk to lockmap. v2 by oqhadev', \&unload);
my $hooks = Plugins::addHooks(
['AI_pre', \&AI_hook],
['is_casting', \&casting_hook],
['parseMsg/pre', \&packet_hook],
['MapSolutionReady', \&getRoute],
);
sub unload {
Plugins::delHooks($hooks);
}
sub checkBlueGem {
my $item = $char->inventory->getByName("Blue Gemstone");
return $item->{amount};
}
sub getRoute {
if (existsInList($config{autoWarp_from}, $field->baseName) && checkBlueGem() && $char->{skills}{AL_WARP} && $char->{skills}{AL_WARP}{lv} > 0) {
message "Preparing to cast a warp portal to $config{autoWarp_to}\n";
AI::clear;
AI::queue("autowarp");
AI::args->{timeout} = 0;
AI::args->{time} = time;
AI::args->{map} = $field->baseName;
}
}
sub AI_hook {
my $hookName = shift;
if (AI::action eq "autowarp") {
if ($field->baseName ne AI::args->{map} || $field->name ne AI::args->{map}) {
AI::dequeue;
return;
}
if (timeOut(AI::args)) {
my $pos = getEmptyPos($char, 4);
$messageSender->sendSkillUseLoc(27, 4, $pos->{x}, $pos->{y});
message "Attempting to open warp portal at $pos->{x} $pos->{y}\n";
AI::args->{timeout} = 5;
AI::args->{time} = time;
}
}
}
sub packet_hook {
my $hookName = shift;
my $args = shift;
my $switch = $args->{switch};
my $msg = $args->{msg};
# Chose warp destination
if ($switch eq "011C" && AI::findAction('autowarp') > -1) {
$messageSender->sendWarpTele(27, $config{'autoWarp_to'}.".gat");
}
}
sub casting_hook {
my $hookName = shift;
my $args = shift;
# it's our warp portal! and we are on autowarp queue, ok lets go in
if ($args->{sourceID} eq $accountID && $args->{skillID} eq 27 && AI::findAction('autowarp') > -1) {
message "Moving into warp portal at $args->{x} $args->{y}\n";
main::ai_route($field->baseName, $args->{x}, $args->{y}, noSitAuto => 1, attackOnRoute => 0);
}
}
sub getEmptyPos {
my ( $obj, $maxDist ) = @_;
my %pos;
# Store positions of other players
foreach my $id (@playersID) {
next unless $id;
my $player = $players{$id};
$pos{ $player->{pos_to}{x} }{ $player->{pos_to}{y} } = 1;
}
my @vectors = ( -1, 0, 1, 0 );
my $vecx = int rand(4);
my $vecy = $vectors[$vecx] ? 2 * int( rand(2) ) + 1 : 2 * int( rand(2) );
my ( $posx, $posy );
for my $i ( 1 .. $maxDist ) {
for my $j ( 0 .. 3 ) {
$posx = $obj->{pos_to}{x} + ( $vectors[$vecx] * $i * -1 );
$posy = $obj->{pos_to}{y} + ( $vectors[$vecy] * $i * -1 );
for my $k ( 0 .. ( $i * 2 - 1 ) ) {
if ( $field->isWalkable( $posx, $posy ) && !$pos{$posx}{$posy} )
{
return { x => $posx, y => $posy }
if $field->canMove( { x => $posx, y => $posy },
$obj->{pos_to} );
}
$posx += $vectors[$vecx];
$posy += $vectors[$vecy];
}
$vecx = ( $vecx + 1 ) % 4;
$vecy = ( $vecy + 1 ) % 4;
}
}
return undef;
}
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment