# Thread: How to organize/simplify this code

1. ## How to organize/simplify this code

Below is part of a much bigger script. Ultimately what I'm trying to do is "simplify" the below function ShroomMove() and make it dynamic.

This is for a game called Maplestory. For those unfamiliar there are mobs that each have unique images for walking, standing, getting hit and dieing. I have this list of images and converted them to bitmaps. In my code all of those bitmaps is for a single mob. What I'm going to be doing is implementing this for multiple mobs, so there's going to be ALOT of bitmaps.

1. If there's a guide or specific term as to what I'm doing please mention it and I can do the leg work just need a push in the right direction.
2. Is it possible to move/store these bitmaps in a separate include to avoid all the clutter?
3. In the function ShroomMove(); Is it possible for me to keep the naming convention the same across all mobs and update this to something like:

Simba Code:
function MobMove(Mob:String): Boolean;begin  if FindBitMapIn(MobMove0L,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);  if FindBitMapIn(MobMove0R,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);  if FindBitMapIn(MobMove1L,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);]end;

Basically what I envision as I'm trying to detect mobs on screen within an attack range; is to do if MobMove(mob, attackRange) then attackRight/attackLeft. Maybe there is a more simple approach to this but any input on this would be appreciated!

Simba Code:
program MapleStory;{$DEFINE SMART}{$I SRL/OSR.simba} var  attackBox: TBox;  x, y, h, ShroomMove0L, ShroomMove1L, ShroomMove2L, ShroomMove3L, ShroomMove0R, ShroomMove1R, ShroomMove2R, ShroomMove3R, ShroomHit0L, ShroomHit0R, ShroomStand0L, ShroomStand0R, ShroomStand1L, ShroomStand1R,  ShroomStand2L, ShroomStand2R: integer;{List of Bitmaps - all of the below bitmaps are individual animations for a single mob, we will be loading large numbers of mobs so this will get big}procedure loadBmps();begin   ShroomMove0L := BitmapFromString(22, 25, 'meJylkWEVhSAMRqlghVfBClawgh' +        'WoYAUqWIEKVKACFfaQ4c7YQN/xcb4fnLF7mWgcmB2MBbOBWTtxocb' +        '6JmbxZ2Z/j5s1EfLZo0iVSDw1KT2abQwbiP5uhniOBn9cY2rZvY4+' +        'lb4exZshxZIgJWyAJzxckkjN3MDrYs6Tgkg4l2jD6DOBr+4YpUe8D' +        'K+AWo2B9dAY3HCDawOeWh9zuiw1CANdig1HSCMJ+YUhV45UZ84bH2' +        'uoSItw7kGKQNzzYB0REWEQf1BL8qZroDas0F/Qw1CbeApxWu6Prw3' +        'X090Z+Je+MBTKre6YN5ujX4zfcu5jaurTlFkKStAzGlhoOa4ljx5u' +        'IDDns6zm7/UFLRov2Q==');  ShroomMove0R := CreateMirroredBitmap(ShroomMove0L);  ShroomMove1L := BitmapFromString(21, 26, 'meJyFlAEVhCAMhqlABStYwQpUsA' +        'IVqGAFKlDBClSgwm5jHDdheLz/+Ty379+GeABwF0gFYgbjwZxg3Kg' +        'zksxxmyOZHRXNhrqMMQDEplzxmT0h3D9VkywcIuM66xp1Zbj4mquD' +        'K92BS09sYe2h6iJtIaPoxmfr7uYQ6sgDSGOSKJ+p0HCSJ7V9+G3XA' +        '2ya1ubJk1jWKcE0IEdIgx5emE9g9Vkgy4dc6MvOhTgNSkYNCQ1vrd' +        'p3du3wv+5ffDUvUXIpDpbT5HO5tfBccwPWWsY5NLzlF/bXZA1JZFX' +        'ap6xUF1EV7NEBbzv8TFBNeum5AV6RPr2CXx8Lf8qJuvPQwxckFm9m' +        'DaCKizY21WSwkji3yiPzmCuc/lieh1xGa4hMojYIN+euuJ++nxMtJ' +        '88NMMhCnKWmzTgejs5KfDvcqkm1LrNIdb3ss9o2U/08fABrdzIK');  ShroomMove1R := CreateMirroredBitmap(ShroomMove1L);  ShroomMove2L := BitmapFromString(19, 29, 'meJyV0guxxCAMBdBYwAIWaqEWaq' +        'EWagELtYAFLGABC1jIC2Sbpny6+5g7nS5wJoQtACBizAgOYUfYuqz' +        'hzuLBnmAcaHVMYLHpggGsL9A4giG/qk8yrPGypWiQQ47gmfCMuPtn' +        'aT7w/JCkXLxt5bnYpdq5+iTezwKLrf2OW8saWpck9w1L7zpr1JsnM' +        'N839sybumKoWbAABn4cpOTVBUn5MHJsJvXqcKmqRJCesw1UcaLSV9' +        'ufQUG2gzPrGd066jFpdnhn+BwzeITEm2eKNgyhzyi2HwIbzlCs5vy' +        'T5iUaspLQqrG2ITzf2JCwscP0UF/mL1agvtJ/FaWZWi29w/6KZlC3' +        'oJWGsk2/b6fnLPvR8OHfwVAUQ4pdt+YTelcCxfZfzns5jm78D4y2QT8=');  ShroomMove2R := CreateMirroredBitmap(ShroomMove2L);  ShroomMove3L := BitmapFromString(20, 26, 'meJy1kmERhCAQRqlABStYwQpWuA' +        'pUsIIVqEAFK1CBCtzCh+uKoN6P23njMLJvd0GVUquPQM1PTD7jwFs' +        'roz9Rui+t1GIrHPobcatZUoVXrnEFiFgPxqv5GUoblgQXKe5oH6DZ' +        'Rgv3wCTUETrTilyBuxeRaio9Le7Euj9X2lUx+FMd/kDJzS+kuFsQA' +        'ec055KKtK460z4gdETfpU1kGuer08UjQgyh6UIv7l4qngMJRNO1W2' +        'D9Gk0XXWyIzieuOp+IYZesCugc0uq1RvceGKnSseZbunGlzjPvQ/r' +        '71sisXOIfrrw0dqt7pi2t9VWcV8uU315ccm+8SiTGjyGk/pNIDNMM' +        'vTpOz5UiXMQX9pwZvA==');  ShroomMove3R := CreateMirroredBitmap(ShroomMove3L);  ShroomHit0L := BitmapFromString(22, 27, 'meJyllHHVhSAMxalABStYwQpWsI' +        'IVrGAFKlCBClSgwt5wOseYvu87j3P/wHHvzwEeASAWiBmWAG7utMC' +        'WYM9VOPELFoubohujG4IbduccQI2HbMXnM1t1cY4XXZCxQuKxasUL' +        'atiyoTX7OTHEr7XVPlsNh54gbKC4X4xslR9cO4jQePqgGNMWUc77e' +        '94sE6GoIDkNv2RSnDldkG1QkpKGnHH/x7iEtISmvZvQj2eILKp4CA' +        'EfU0oSYhKo3hO4yYuQjdMQW9Z+/OZjfOpBXha9i5bWmO1DuAjk6Qn' +        'cM66+QSyC9OMkpPIEYb/65LASyrkajn8FiYs8iIxBBUGnlKrUx3zv' +        'jqUI1HPIxSYU4M2qLxBFNrVqtoSTeQ+ocVmHaWaIJFBvfDKqB4r3E' +        'CbQ6VWU95KgGmACQ9jDVxCvc/svoYUUnpiEF8iLntogyHcONpOLvA' +        '4V/2V8AE3zZ5A=');  ShroomHit0R := CreateMirroredBitmap(ShroomHit0L);  ShroomStand0L := BitmapFromString(22, 27, 'meJylkWG1wyAMRmNhFmphFmqhFm' +        'qhFmqhFmoBC1jAAhbyUsKykEC3s8f5fnBC7iWlAICIMWPICBvCirB' +        '0csQaWDLM4cozwHRSGId9jK+4x7eherTkuMXV7Vto8pbc4jSzINOe' +        'TKrE4rlJ6fFsY1jR9HczxCke/HKNqXkPPv7U+nqUbsacSqKVqAE+4' +        'fElSdKsDbpu5rwoTIJriTeMPhP16o5ReszL6Aq61RhUj4yhDTe4N/' +        'DpFhKly0qDMcil3HDGPJKI3xiocuY6M21CqpGiLMG1hykBea/DdUZ' +        'MjMH8QS+hTdcgbVyRv+CHkTbzFOa03J9+Nrye7s6gv/QHQ6GO5Tif' +        '60bxL6ZvufYpN/XHg1gJS9gzGthoNe4lHz3aICBlmhf49/oD2Cl2xQ==');  ShroomStand0R := CreateMirroredBitmap(ShroomStand0L);  ShroomStand1L := BitmapFromString(22, 27, 'meJyllGG1gzAMRmMBC1jAAhawgA' +        'UsYKEWaqEWsFALtZCXNSwLSenetp7vR0+ae9sVGAAgYiqYMsKGsLQ' +        'TjjOwFJgSTBFGSoAhMA57xdcWvuJ+vAynR0tCF1e7b+mSh2Sski5O' +        'ZxZk3LPJKbF4uWROFM++DJQVTX8zDZyXyODBf457at6Tj1+yvhalm' +        '2+16gCf4sbQ7Hx7PGMwkvcXqSWtgSXrucnF4Pq5LpUObgyCbClToH' +        '6zfjSf6bnpsyEe5U4ifmOgSizI81j/KDhSlCG4kVCngDzX4TqzOt5' +        'gnqCX0KRpkDYu8m83Bh0vMat1//y14Xl1PYN/LT8yVCosIU7rRvE3' +        'pnd5zHO51IeBWAlLxnnpHNhoNa4lncPcGQTU+C/jDwZGSAU=');  ShroomStand1R := CreateMirroredBitmap(ShroomStand1L);  ShroomStand2L := BitmapFromString(22, 27, 'meJyllGERgzAMRmMBC1jAAhawgA' +        'Us1EItYKEWZqEWsNBlDRfSpC1j474fvTTvNXAAAKSUwpFCTLAmWOr' +        'xrzOwHDAHmDA7jB4GRzhsbXxN7nUZTg9Jxh0GD66Li9O3UOSSdHGc' +        'mZHRRZVTovGjCPbMwbKFQVK5v5o6TrHgl1ebml2wsVvaV6Nkc1MrB' +        'niKK0O183Y8ZVCS21srJAaUlS1ETvUguni3g1NsM1VUvYrbs6SBG/' +        'Abx8iKnFPeizLs+f+gwkX1KJQHDdjJzbSWsZKWQb2oVoKLqoHbqAj' +        '5p6cMMh0D7ebz488GzK3Bfo+PDJnyi9+ndcPYJyZP+azjUdSHAVkO' +        'ScZ56QystBKXks4wLQODEv/negN291ni');  ShroomStand2R := CreateMirroredBitmap(ShroomStand2L);end;function ShroomMove(): Boolean;begin  if FindBitMapIn(ShroomMove0L,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);  if FindBitMapIn(ShroomMove0R,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);  if FindBitMapIn(ShroomMove1L,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);  if FindBitMapIn(ShroomMove1R,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);  if FindBitMapIn(ShroomMove2L,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);  if FindBitMapIn(ShroomMove2R,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);  if FindBitMapIn(ShroomMove3L,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);  if FindBitMapIn(ShroomMove3R,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);  if FindBitMapIn(ShroomHit0L,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);  if FindBitMapIn(ShroomHit0R,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);  if FindBitMapIn(ShroomStand0L,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);  if FindBitMapIn(ShroomStand0R,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);  if FindBitMapIn(ShroomStand1L,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);  if FindBitMapIn(ShroomStand1R,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);  if FindBitMapIn(ShroomStand2L,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);  if FindBitMapIn(ShroomStand2R,x, y, IntToBox(340, 400, 705, 460)) then    exit(true);end;begin  LoadBmps();  wait(5000);  repeat    while isKeyDown(116) do //waits while F5 is held      wait(1000);    writeln(ShroomMove());    wait(1000);  until false;end.

2. Originally Posted by Clutch
...
Yes, you can put all that code in an include. Just save it to another file in your includes folder, then include it in your main script.
You could also save all those bitmaps as files and load them that way without all the BitmapFromString code.

You can simplify your ShroomMove function by just putting all the bitmaps in an array and looping through it.
One thing to consider here is that the screen could change between checking for each bitmap and you could get a false negative. One way to avoid this is to save a bitmap of the screen and use it for all your searches.
BitmapFromClient and SetTargetBitmap should get the job done.

3. Originally Posted by Citrus
One thing to consider here is that the screen could change between checking for each bitmap and you could get a false negative. One way to avoid this is to save a bitmap of the screen and use it for all your searches.
BitmapFromClient and SetTargetBitmap should get the job done.
I did all of the other stuff, thanks for your input on that. Regarding the above though, I'm pretty sure this won't be an issue? Basically your saying that the function may take 1000ms+ to iterate through all the bitmaps and by that time the mob may have moved out of screen yeah?

The game is 2D and the mobs are constantly moving but for the most part if they're in screen and especially within my attack range (TBox), it triggers I'll be sending a key to attack. I have my attack range slightly smaller than it's "full range" to accomodate for delays so I think that takes care of any false negatives if I'm following you?

I was previously using color for this but majority of the mobs tend to blend in with the rest of the environment and lack any unique colors so this fills that gap. Switching to bitmaps has been a HUGE help!

4. I'm not familiar with Maplestory, but using this many bitmaps is just going to be slow, no way around it without multithreading (which you can't do natively on Simba as far as I know, at least currently), are you just trying to detect the mobs, and not detect them in a certain sprite?

The way I normally find mobs which have similar colors is to find ATPA Boxes for a color of the mob (say the least found colour first), then search within those boxes in an array for some other colours (count some colours in the boxes and if the other colors are over an amount then it's likely your mob), then you can identfy a mob in any sprite mode with just 2-4 color searches in a small area which is much faster than bitmaps.

Get the inital boxes to be as few as possible (the false positives) and it will greatly speed up your search.

5. Originally Posted by Clutch
Regarding the above though, I'm pretty sure this won't be an issue? Basically your saying that the function may take 1000ms+ to iterate through all the bitmaps and by that time the mob may have moved out of screen yeah?
No, I'm saying that the animation could tick between your checks for each pose.
e.g. The mob in in pose B -> you check for pose A (false) -> mob switches to pose A -> you check for pose B (now false).
Your script will work fine without accounting for this, but I thought it was worth mentioning since it's a slightly "more correct" way to do things.
Last edited by Citrus; 07-25-2020 at 04:02 AM.

6. Originally Posted by Citrus
No, I'm saying that the animation could tick between your checks for each pose.
e.g. The mob in in pose B -> you check for pose A (false) -> mob switches to pose A -> you check for pose B (now false).
Your script will work fine without accounting for this, but I thought it was worth mentioning since it's a slightly "more correct" way to do things.
There is Freeze() and UnFreeze() for this.

Simba Code:
Freeze();FindBitmap(...);FindBitmap(...);FindBitmap(...); // EtcUnFreeze()

7. ^ There you go, a much simpler solution.

8. Originally Posted by DannyRS
I'm not familiar with Maplestory, but using this many bitmaps is just going to be slow, no way around it without multithreading (which you can't do natively on Simba as far as I know, at least currently), are you just trying to detect the mobs, and not detect them in a certain sprite?

The way I normally find mobs which have similar colors is to find ATPA Boxes for a color of the mob (say the least found colour first), then search within those boxes in an array for some other colours (count some colours in the boxes and if the other colors are over an amount then it's likely your mob), then you can identfy a mob in any sprite mode with just 2-4 color searches in a small area which is much faster than bitmaps.

Get the inital boxes to be as few as possible (the false positives) and it will greatly speed up your search.
I'm simply trying to detect the mob, which sprite the mob is showing as is irrelevant. Each map (that I'm training on)only has 3 separate mobs max, at a single time (generally only 1 unique npc) so currently it's more than fast enough for finding them as I'm only loading 6-18 bitmaps at a time. I'm changing this up depending on which map I'm using so I don't end up loading hundreds of bitmaps.

I believe I understand your approach and is something I could possibly look into further. Attached is an image of two different mobs (Red Snail/Blue Snail) alongside their "drops". I believe in this particular instance the above would work as I could search by the shell color (same for drop and npc) and the snails "skin"(?) to determine if it's a drop vs live npc.
Example1.PNG

The only true issue I see with this is the NPC drops may cause some problems. It's likely 1 of the "common" drops is identical to the "main" color, and 1 of the uncommon drops is identical to the secondary color which could cause the bot to stand there and spam attack. Given it's maplestory, you can burn through 100+ npcs relatively quickly and with modified drop rates, it's not uncommon to go through the rather extensive list of monster drops. While I do think this has potential, until bitmaps begin giving me performance issues I think they will continue to work although I'm always open for additional ideas especially if it leads me to learn more.

Thanks for the idea!

Edit: Also worth mentioning... most maps, 1 distinct color and the right settings is more than enough to detect mobs. This is really for the one off locations that have those unique drops or are just for simple early training until I can get to those "key" locations that are simple to detect on.
Last edited by Clutch; 07-27-2020 at 11:14 PM.

9. Registered User
Join Date
Feb 2015
Posts
8
Mentioned
0 Post(s)
Quoted
0 Post(s)
What are you looking to do with simba and maplestory? It's a pretty easy game you could just use some mouse/keyboard inputs, Most probably not even worth trying colour with the amount of mobs/ levels also picking up drops is a tedious thing if you're only trying to pick up certain ones rather than just spamming the loot button.