By catcity
What's the digs?
Okay; this is my first plugin. Ever. This is also the first time I have ever seen perl before in my life so the whole thing is a little hacked together. To get myself started I wanted to take one of my clunky old macros and make it a little more elegant and functional; and with a little help from some dudes over on IRC (Harvest; ChristphR) I've got it to a state where it actually works. If it's useful to you then feel free to use it. I'm all about sharing, bros.
A little side note about this topic: I am documenting the plugin, which means this topic has a lot of words. I want to make it so if you are the kind of person that has downloaded kore and has never installed a plugin before and is feeling a little overwhelmed by the whole thing then you will find it easy. If you already know how to install a plugin and configure it then just scroll on down to the code block and check out the documentation that is included in the code.
But what does it do?
It allows your bot to roam a little more freely while keeping the reigns on. Essentially it allows you to have multiple lockMaps and after a given time (set by you, the user) it will randomly pick one of those lockMaps out of a hat and set that as the current map in your config.
It's possible to do this very easily with macros, but macros break, and macros run into each other. It's also possible to do this in the core functionality of openkore by changing to a different config after a given period of time; but again, why make a whole 'nother config file when you can just adjust a few lines of your current config.
How do I set it up?
First thing's first; go ahead and grab the following code block and save it as automap.pl in your openkore plugins folder. If that plugins folder doesn't exist go ahead and create it: (Technically you can name it whatever the hell you want. Just dump this junk into a text file and save it as *.pl)
Code: Select all
#. Automatic Map Changer
#. By catcity
#. CONFIGURATION
#. Add These Lines to config.txt:
#. autoMapChange [0|1]
#. autoMapChange_time [Number of Seconds]
#. autoMapChange_timeSeed [Number of Seconds]
#. autoMapChange_list [Comma Seperated List]
#. autoMapChange is a boolean. Set it to 0 to turn the plugin off. Set it to 1 to turn the plugin on.
#. autoMapChange_time is the number of seconds that you would like the plugin to wait until the next map change.
#. autoMapChange_timeSeed is a random seed. The plugin will take any amount of seconds between 0 and the number you set here and add it to the time.
#. autoMapChange_list is a comma seperated list of lockMaps that you would like the plugin to randomly draw from.
#. EXAMPLE CONFIG.TXT
#. autoMapChange 1
#. autoMapChange_time 3600
#. autoMapChange_timeSeed 3600
#. autoMapChange_list prt_fild01, prt_fild02, prt_fild03, prt_fild04
#. Between every 60 and 120 minutes this example config will randomly choose a map from the list and set it as your lockMap.
#. It is possible that it will select the same map from the list twice in a row.
#. It is possible that it will select the same map from the list three times in a row.
#. It is possible that it will... Well you get the message.
#. You can use this to give preference to certain maps that you want to spend more time on than others.
#. Add multiple instances of the same map to the list and it has a greater chance of being the selected map.
#. CONSOLE COMMANDS
#. Automatic Map Changer has two additional console commands.
#. Typing 'automapc' into the console forces an immediate random change and resets the time.
#. Typing 'automapt' into the console gives the time since last change and the time until the next change.
package autoMapChange;
use strict;
use Plugins;
use Globals;
use Network;
use Misc;
use Log qw(debug message warning error);
use Commands;
use Time::HiRes qw(gettimeofday tv_interval);
Plugins::register('autoMapChange', \&on_unload, \&on_reload);
my $hooks = Plugins::addHooks(
['mainLoop_pre', \&on_mainLoop],
['start3', \&on_start],
);
my $commands = Commands::register(
['automapt', 'Check Automap Timings', \&cmdMapTime],
['automapc', 'Force an Automap Change', \&cmdMapChange],
);
my $changeTime = 0;
my $timeElapsed01 = 0;
my $validation = 0;
sub on_unload {
Plugins::delHooks($hooks);
Commands::unregister($commands)
}
sub on_reload {
&on_unload;
}
sub on_start {
if ($config{'autoMapChange'}) {
message "\n";
message "########################################\n";
message "VALIDATING AUTOMATIC MAP CHANGER CONFIG.\n";
message "\n";
if ($config{'autoMapChange_time'} eq "") {
configModify('autoMapChange_time', 3600, 1);
warning "Detected that your autoMapChange_time config is undefined.\n";
warning "Automatically setting autoMapChange_time to 3600 seconds [1 Hour]\n";
message "\n";
$validation -= 1;
}
elsif ($config{'autoMapChange_time'} <= 120 && $config{'autoMapChange_time'} != 0) {
warning "Detected that your autoMapChange_time is set to a very low value.\n";
warning "This can have a negative impact on your bot performance.\n";
message "\n";
$validation -= 1;
}
elsif ($config{'autoMapChange_time'} == 0) {
configModify('autoMapChange', 0, 1);
warning "Detected that your autoMapChange_time has been set to 0.\n";
warning "This will spam your bot with lockMap changes.\n";
error "Disabling autoMapChange plugin..\n";
message "\n";
$validation -= 1;
}
elsif ($config{'autoMapChange_time'}) {
message "Time config is declared.\n";
message "\n";
$validation += 1;
}
if ($config{'autoMapChange_timeSeed'} eq "") {
configModify('autoMapChange_timeSeed', 0, 1);
warning "Detected that your autoMapChange_timeSeed is undefined.\n";
warning "Automatically setting autoMapChange_timeSeed to 0.\n";
message "\n";
$validation -= 1;
}
elsif ($config{'autoMapChange_timeSeed'}) {
message "Seed config is declared.\n";
message "\n";
$validation += 1;
}
elsif ($config{'autoMapChange_timeSeed'} == 0) {
message "Seed config is declared as 0.\n";
message "This is fine, but please note that it is for precision time changes.\n";
message "Your lockMap will change exactly on the time specified with no randomness or variation.\n";
message "\n";
$validation += 1;
}
if ($config{'autoMapChange_list'} eq "") {
configModify('autoMapChange', 0, 1);
warning "Detected that your autoMapChange_list is empty.\n";
error "Disabling autoMapChange plugin.\n";
message "\n";
$validation -= 1;
}
elsif ($config{'autoMapChange_list'}) {
message "List config is declared.\n";
message "\n";
$validation += 1;
}
if ($validation < 3) {
warning "Please review your configuration for the automatic map changer plugin in config.txt.\n";
message "########################################\n";
}
elsif ($validation == 3) {
message "Everything okay!\n";
message "########################################\n";
}
}
}
sub on_mainLoop {
if ($config{'autoMapChange'} && time - $KoreStartTime > $changeTime && $net->getState() == Network::IN_GAME) {
my @lockMapList = split(/,\s*/, $config{'autoMapChange_list'});
my $lockMapNew = $lockMapList[rand @lockMapList];
configModify('lockMap', $lockMapNew, 1);
message "Setting lockMap to '$lockMapNew' [After $changeTime seconds]\n";
$timeout_ex{'master'}{'time'} = time;
$KoreStartTime = time + $timeout_ex{'master'}{'timeout'};
initChangeMap();
}
}
sub initChangeMap {
if ($config{'autoMapChange'}) {
$changeTime = $config{'autoMapChange_time'} + int(rand $config{'autoMapChange_timeSeed'});
$timeElapsed01 = [gettimeofday];
}
}
sub cmdMapTime {
if ($config{'autoMapChange'} && $net->getState() == Network::IN_GAME) {
my $timeElapsed02 = tv_interval ($timeElapsed01, [gettimeofday]);
my $rounded = int($timeElapsed02);
my $timeUntil = $changeTime - $rounded;
message "It has been ($rounded) seconds since your last lockMap change.\n";
message "Your next change will occur in ($timeUntil) seconds.\n";
}
}
sub cmdMapChange {
if ($config{'autoMapChange'} && $net->getState() == Network::IN_GAME) {
my @lockMapList = split(/,\s*/, $config{'autoMapChange_list'});
my $lockMapNew = $lockMapList[rand @lockMapList];
configModify('lockMap', $lockMapNew, 1);
message "Setting lockMap to '$lockMapNew' [Request by User]\n";
$timeout_ex{'master'}{'time'} = time;
$KoreStartTime = time + $timeout_ex{'master'}{'timeout'};
initChangeMap();
}
}
return 1
Code: Select all
autoMapChange
autoMapChange_time
autoMapChange_timeSeed
autoMapChange_list
The first line is autoMapChange. This is your on and off switch for the plugin. If you ever want to turn it off set the line to 0. If you want to turn the plugin on, set the line to 1.
Code: Select all
autoMapChange 1
Code: Select all
autoMapChange_time 3600
Code: Select all
autoMapChange_timeSeed 1800
Code: Select all
autoMapChange_list prt_fild01, prt_fild02, prt_fild03, prt_fild04
It is possible that the plugin will choose the same map twice. As the plugin just draws any value randomly from the list, it is possible that it will draw the same map twice. In the above example, if you're on prt_fild01 and it has been 3600 seconds + up to 1800 seconds and the plugin kicks in to choose a new map; it might just go ahead and pick prt_fild01 all over again and leave you there for another hour or so until the next time it kicks in (at which point it might leave you there again.) This is intentional because I feel it adds to the randomness of the plugin, but of course the more maps you have in your list, the less likely it is that this will occur. That brings me on to another thing...
You can weight the choices by including duplicates. In the above example there are four maps listed. prt_fild01, prt_fild02, prt_fild03 and prt_fild04. With this setup of four maps, when the plugin triggers there is a 25% chance that any one of those maps will be selected. But what if I had the following setup:
Code: Select all
autoMapChange_list prt_fild01, prt_fild01, prt_fild02, prt_fild03
Console Commands
It's not all config control though! I've thrown in a couple of console commands for when you're playing and don't want to be fiddling around with text files.
Code: Select all
automapt
Code: Select all
automapc
What's this validation?
I have tried to put in some measures to make it so that the plugin will not screw things up if it's not configured properly, but like I say: This is my first plugin, this is my first time with perl and this plugin is not extensively tested. All I will say is; don't set your time changes too low. The plugin should disable itself if you set it to 0 seconds which will spam lockMap changes. It should give you a warning if you set it below two minutes between changes, but really anything below 30 minutes is probably going to screw with the efficiency of your bot. Remember, you have to factor in travel time for your bot moving between the maps.
That brings us into one last thing. Make sure you know where your maps are set in relation to your savemap and how your bot is going to move between all the maps. It would suck if you left your bot running and came back to find he/she has spent the last hour dying because it was trying to roam through a hostile map to get to where it needed to go, or that you've lost all your money because it's been using kafra warps to get there each time. Just do a little bit of research in that department.
Features that I will maybe consider adding at a later date/time if I can figure out how:
Change saveMap in line with lockMap.
Cluster lockMaps so bot will roam between adjacent maps that are listed in the file.
Suggestions...
With all that said...
I'll stop talking now. I hope this is useful to someone other than me. I know it's nothing special, but if you're like me and don't like keeping your bot in one place for too long, then this is for you. If you find any bugs or issues, post them back here. If you have feedback, post it back here.
Cheers,
catcity