Automatic Map Changer

Other plugins for extending OpenKore's functionality. This forum is only for posting new plugins and commenting on existing plugins. For support, use the Support forum.

Moderator: Moderators

Message
Author
catcity
Noob
Noob
Posts: 18
Joined: 20 Oct 2012, 14:31
Noob?: No

Automatic Map Changer

#1 Post by catcity »

Automatic Map Changer
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
Then open up your config.txt and add the following lines (I recommend pasting them in just under your current lockMap block. Keep it all together!):

Code: Select all

autoMapChange
autoMapChange_time
autoMapChange_timeSeed
autoMapChange_list
If you've installed the plugin correctly these lines should be all you need to configure. I'll talk you through it.

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
The next line is autoMapChange_time. This is the number of seconds that we want the plugin to wait before changing your lockMap. If you want to swap lockMap every 30 minutes then set it to 1800. If you want to swap lockMap every hour then set it to 3600.

Code: Select all

autoMapChange_time 3600
The next line is autoMapChange_timeSeed. This is a maximum number of seconds that the plugin will wait additional to the time that has been set before changing the map. It gives some randomness, variety and unpredictability to the bot (in a good way). So if you have set the autoMapChange_time to 3600 and autoMapChange_timeSeed to 1800, the bot will wait 3600 seconds THEN a random number of seconds between 0 and 1800 before changing to a new map.

Code: Select all

autoMapChange_timeSeed 1800
The final line is autoMapChange_list. This is a comma separated list of maps that the plugin will draw from to set your new lockMap. Just drop the map names in there and all should be swell as long they are valid!

Code: Select all

autoMapChange_list prt_fild01, prt_fild02, prt_fild03, prt_fild04
A couple of notes about your list of lockMaps:

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
Well now there is a 50% chance that it is going to be prt_fild01, and a 25% chance each that it is going to be 02 or 03. If you were that way inclined you could set this up quite easily so you are preferring a particular map. If you want to spend the majority of your time on one map, but some of the time on another then that's possible.

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
Typing automapt into the console just feeds back to you a couple of stats. The time in seconds since your last map change and the time in seconds until your next change. With longer seed times it can leave you wondering when that change is going to happen so this will tell you exactly how long you have to wait.

Code: Select all

automapc
Typing automapc into the console will force an immediate change and reset the timer. For whatever reason you check up on your bot and the map you're on is overcrowded, or maybe you just feel like you've been there too long. This will change things up a bit.

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
There's two types of people in this world, kid: Those who can, and those who can't; and cats...

[Plugin] Automatic Map Changer

ffej
Noob
Noob
Posts: 3
Joined: 06 Nov 2012, 08:15
Noob?: No

Re: Automatic Map Changer

#2 Post by ffej »

Cheers catcity - this is a useful plugin to have shared!

I'll let you know if there are any issues/bugs

catcity
Noob
Noob
Posts: 18
Joined: 20 Oct 2012, 14:31
Noob?: No

Re: Automatic Map Changer

#3 Post by catcity »

Hey, thanks!

It's just a little thing that I wanted for myself and figured that other people might like it too; so if you have any suggestions for improving it then go ahead and spitball 'em at me.
There's two types of people in this world, kid: Those who can, and those who can't; and cats...

[Plugin] Automatic Map Changer

iMikeLance
Moderators
Moderators
Posts: 208
Joined: 01 Feb 2010, 17:37
Noob?: No
Location: Brazil - MG
Contact:

Re: Automatic Map Changer

#4 Post by iMikeLance »

catcity wrote: A couple of notes about your list of lockMaps:

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
Well now there is a 50% chance that it is going to be prt_fild01, and a 25% chance each that it is going to be 02 or 03. If you were that way inclined you could set this up quite easily so you are preferring a particular map. If you want to spend the majority of your time on one map, but some of the time on another then that's possible.
This is a VERY useful plugin and well documented.
Maybe you could add a loop to the code where you pick a random map from the list until selected map != $config{lockMap}.
It would be very nice if you could also trigger the map changes with some conditions and add some new ones. afterStorageAuto would be a good one and you can easily do it by using 'AI_storage_done' hook.
In case you need any help you can ask me anything.

EternalHarvest
Developers
Developers
Posts: 1798
Joined: 05 Dec 2008, 05:42
Noob?: Yes

Re: Automatic Map Changer

#5 Post by EternalHarvest »

iMikeLance wrote:It would be very nice if you could also trigger the map changes with some conditions and add some new ones.
I can suggest block-based configuration with self conditions, where a lot of default and custom (from other plugins) conditions exist.

Something like this, where all maps from all currently valid blocks would be used:

Code: Select all

autoMapChange_time
autoMapChange_timeSeed
autoMapChange <map>, <map>... {
  <self conditions>
  time (optional, only to override global setting)
  timeSeed (optional, only to override global setting)
}
autoMapChange ... {
   ...
}
Maybe also it's better to name them timeoutMin/timeoutMax instead of time/timeSeed, to be more alike already existing options with similar behaviour? (http://wiki.openkore.com/index.php/homu ... TimeoutMin, are there more similar?)

catcity
Noob
Noob
Posts: 18
Joined: 20 Oct 2012, 14:31
Noob?: No

Re: Automatic Map Changer

#6 Post by catcity »

In terms of the !config{'lockMap'} feature. I did think about it, and for my own purposes I was happy to have it select the same map multiple times so I could weight maps with preference. However, you are right that it should be an optional field so I will look at including that.

I really like the idea of block based config, but as this was my first plugin it was a bit above my level of capability. I want to look into it though so leave both of these suggestions with me and I'll see what I can do.
There's two types of people in this world, kid: Those who can, and those who can't; and cats...

[Plugin] Automatic Map Changer

User avatar
ChrstphrR
Testers Team
Testers Team
Posts: 42
Joined: 09 May 2010, 17:30
Noob?: No
Location: Northern Alberta, Canada

Re: Automatic Map Changer

#7 Post by ChrstphrR »

A minor change I'd suggest, because the output of 'plugin' will show a not so nice CODE() entry for the description. I don't know if that means the &on_unload subroutine isn't linked where it ought to be or not because of the missing description field.

Code: Select all

Plugins::register('autoMapChange', 'Change up lockMap field chosen from a list', \&on_unload, \&on_reload);
The posted plugin is even better than the dev version I was demoing, especially the validation routine. Job well done!

EternalHarvest
Developers
Developers
Posts: 1798
Joined: 05 Dec 2008, 05:42
Noob?: Yes

Re: Automatic Map Changer

#8 Post by EternalHarvest »

ChrstphrR wrote:I don't know if that means the &on_unload subroutine isn't linked where it ought to be or not because of the missing description field.
Yes, as these are plain usual function arguments which can't be just omitted.

kadaj
Noob
Noob
Posts: 5
Joined: 31 Dec 2009, 15:25
Noob?: No
Location: in your head
Contact:

Re: Automatic Map Changer

#9 Post by kadaj »

nice plugin! a little suggestion, maybe you can add a condition when your character reach a certain level is that it would change it's lockmap, because since renewal you need to change your leveling spot based on your level. i'll try working on your plugin tonight when i got home and share on what I have done.

NiTRO106
Plain Yogurt
Plain Yogurt
Posts: 64
Joined: 30 Nov 2012, 20:27
Noob?: No

Re: Automatic Map Changer

#10 Post by NiTRO106 »

very nice plugin! it can save time and effort. :)

Post Reply