I did a major work (about continuous 10 hrs) last night for this thing "To plan walk".
I merge my planWalk.pl and the WayPoint and the macro.pl to make a new planLockMapWalk plugin.
As following:
Code:
# planLockMapWalk by Snoopy Chen 2011/3/5
package planLockMapWalk;
use strict;
use Time::HiRes qw(time);
use Globals;
use Utils;
use Misc;
use AI;
use Log qw(debug message warning error);
use Translation;
my $nSpot = 0;
my $planMap = "";
my $cfID;
my $planwalk_file = "";
my @points = ();
Plugins::register('planLockMapWalk', 'Auto Plan to walk.', \&on_unload, \&on_reload);
my $hooks = Plugins::addHooks(
['configModify', \&on_configModify, undef],
['start3', \&on_start3, undef],
['postloadfiles', \&on_loadfiles, undef],
['pref_RandomWalk', \&pref_planWalk, undef],
['post_RandomWalk', \&post_planWalk, undef]
);
my $chooks = Commands::register(
['planwalk', "Plan Lock Map Walk plugin", \&commandHandler]
);
sub on_unload {
Plugins::delHooks($hooks);
}
sub on_reload {
message "planLockMapWalk plugin reloading\n";
Plugins::delHooks($hooks);
&on_start3
}
sub on_configModify {
my (undef, $args) = @_;
if ($args->{key} eq 'planWalk_file') {
$planwalk_file = $args->{val};
Settings::removeFile($cfID);
$cfID = Settings::addControlFile($planwalk_file, loader => [ \&parsePlanWalk, undef]);
Settings::loadByHandle($cfID);
} elsif ($args->{key} eq 'lockMap') {
if ($planMap ne $args->{val}) {
$planMap = $args->{val};
$nSpot = 0;
Settings::loadByHandle($cfID);
}
}
}
sub on_start3 {
&checkFile;
Settings::removeFile($cfID) if ($cfID);
$cfID = Settings::addControlFile($planwalk_file, loader => [ \&parsePlanWalk]);
Settings::loadByHandle($cfID);
}
sub on_loadfiles {
if ($char && ($planMap ne $config{lockMap} || $planwalk_file ne $config{planWalk_file})) {
$planMap = $config{lockMap};
$planwalk_file = (defined $config{planWalk_file})? $config{planWalk_file} : "planwalk.txt";
Settings::removeFile($cfID) if ($cfID);
$cfID = Settings::addControlFile($planwalk_file, loader => [ \&parsePlanWalk]);
Settings::loadByHandle($cfID);
}
}
# checks planwalk file
sub checkFile {
$planMap = $config{lockMap};
$planwalk_file = (defined $config{planWalk_file})? $config{planWalk_file} : "planwalk.txt";
}
# onFile(Re)load
sub parsePlanWalk {
my $file = shift;
my $flag1 = 0;
@points = ();
if (-e $file && $planMap) {
open my $fp, "<:utf8", $file;
while (<$fp>) {
$. == 1 && s/^\x{FEFF}//; # utf bom
s/(.*)[\s\t]+#.*$/$1/; # remove last comments
s/^\s*#.*$//; # remove comments
s/^\s*//; # remove leading whitespaces
s/\s*[\r\n]?$//g; # remove trailing whitespaces and eol
s/ +/ /g; # trim down spaces - very cool for user's string data?
next unless ($_);
if (/^\[(.+)\]$/) {
$flag1 = ($1 eq $planMap) ? 1 : 0;
} elsif ($flag1) {
if (/^(\d+):(\d+)$/) {
push @points, {'xPos' => $1, 'yPos' => $2};
}
}
}
}
}
sub pref_planWalk {
return if (!$config{autoPlanLockMapWalk} || $config{lockMap} ne $field->baseName);
my (undef, $args) = @_;
my $ret = 1;
$nSpot = @points - 1 if ($nSpot >= @points);
if ($nSpot >= 0) {
my ($to_x, $to_y);
$to_x = $points[$nSpot]->{xPos};
$to_y = $points[$nSpot]->{yPos};
if ($to_x eq "" || $to_y eq "") {
error T("Empty coordinates setting for planLockMapWalk; planLockMapWalk disabled\n");
$config{autoPlanLockMapWalk} = '0';
} elsif ($field->isWalkable($to_x, $to_y)) {
AI::clear(qw/move route mapRoute/);
message TF("Do plan walking route to: %s: %s, %s\n", $field->descString(), $to_x, $to_y), "route";
main::ai_route($field->baseName, $to_x, $to_y,
maxRouteTime => $config{route_randomWalk_maxRouteTime},
attackOnRoute => 2,
noMapRoute => ($config{route_randomWalk} == 2 ? 1 : 0));
$ret = 0;
} else {
error T("Invalid coordinates specified for planLockMapWalk (coordinates are unwalkable); planLockMapWalk disabled\n");
$config{autoPlanLockMapWalk} = '0';
}
$nSpot++;
$nSpot = 0 if ($nSpot >= @points);
}
$args->{return} = $ret;
}
sub post_planWalk {
}
sub commandHandler {
message TF("The Plan Lock Map is : %s (Step: %d)\n", ($planMap) ? $planMap : "???", $nSpot - 1);
message TF("The configuration file is : %s \n", ($planwalk_file) ? $planwalk_file : "???");
for(my $i = 0 ; $i < @points ; $i++) {
message TF("Walk Point(%d) : %s, %s\n", $i, $points[$i]->{xPos}, $points[$i]->{yPos});
}
}
1;
But, it needs modifing the code "sub processRandomWalk" of src/AI/CoreLogic.pm.
I add two Plugins::callHook's : 'pref_RandomWalk' and 'post_RandomWalk'.
Acturly, I only use the 'pref_RandomWalk'. The new "sub processRandomWalk" is:
Code:
##### RANDOM WALK #####
sub processRandomWalk {
if (AI::isIdle && (AI::SlaveManager::isIdle()) && $config{route_randomWalk} && !$ai_v{sitAuto_forcedBySitCommand}
&& (!$field->isCity || $config{route_randomWalk_inTown})
&& length($field->{rawMap}) ) {
my %hookArgs;
$hookArgs{prefix} = "pref_RandomWalk";
$hookArgs{return} = 1;
Plugins::callHook('pref_RandomWalk', \%hookArgs);
if ($hookArgs{return}) {
my ($randX, $randY);
my $i = 500;
do {
$randX = int(rand($field->width)) + 1;
$randX = int($config{'lockMap_x'} - $config{'lockMap_randX'} + rand(2*$config{'lockMap_randX'}))+1 if ($config{'lockMap_x'} ne '' && $config{'lockMap_randX'} ne '');
$randY = int(rand($field->height)) + 1;
$randY = int($config{'lockMap_y'} - $config{'lockMap_randY'} + rand(2*$config{'lockMap_randY'}))+1 if ($config{'lockMap_y'} ne '' && $config{'lockMap_randY'} ne '');
} while (--$i && !$field->isWalkable($randX, $randY));
if (!$i) {
error T("Invalid coordinates specified for randomWalk (coordinates are unwalkable); randomWalk disabled\n");
$config{route_randomWalk} = 0;
} else {
message TF("Calculating random route to: %s: %s, %s\n", $field->descString(), $randX, $randY), "route";
ai_route($field->baseName, $randX, $randY,
maxRouteTime => $config{route_randomWalk_maxRouteTime},
attackOnRoute => 2,
noMapRoute => ($config{route_randomWalk} == 2 ? 1 : 0) );
}
}
$hookArgs{prefix} = "post_RandomWalk";
$hookArgs{return} = 1;
Plugins::callHook('post_RandomWalk', \%hookArgs);
}
}