[Request] Nostale Online Scripts -UPDATED-

You may request or share scripts for MicroMacro in this forum.
Post Reply
Message
Author
Mesosmagnet
Posts: 37
Joined: Wed Apr 23, 2008 7:11 am

[Request] Nostale Online Scripts -UPDATED-

#1 Post by Mesosmagnet » Wed Apr 23, 2008 7:29 am

I have been using the very very old version of minimacro for a month now and today I saw that there is a new version which allows me to perform much more complex tasks. Most of the code I saw for the PW script confused me .. so I'm still in the process of learning how to use minimacro to its full potential. Anyway, while I'm learning how to write my own script I would like to see what others come up with. So here goes.

The script might include:
Attacking monsters (if possible only attack certain monster)
Using potions when HP falls below 30%
Using potions when MP falls below 30%
Picking up items (being able to move to the item and pick it up)
Resting(sitting down) if HP is more than 30% and monster is dead
Using potions on Pets and Partners when HP falls below 30%
Respond when name is used by other player
Drop unwanted/useless items.

Hehe since Nostale(Global) was just released on April 1st for OB so not many hackers have hit it yet. So good luck to me and I hope that I can get a few examples of scripts too! Thanks in advance!
---------------------------------------------------------------------------------------------------
--SETTINGS
---------------------------------------------------------------------------------------------------

HP_potion = 100;
MP_potion = 50;
HP_restatm = 150
MP_restatm = 100

key_attack = key.VK_SPACE;
key_pickup = key.VK_X;
key_skill1 = key.VK_1;
keyskill2 = key.VK_2;
keyskill3 = key.VK_3;

key_hppotion = key.VK_4;
key_mppotion = key.VK_5;

-----------------------------------------------------------------------------------------------------
--ADDRESSES
-----------------------------------------------------------------------------------------------------


proc = 0;
win = 0;
HP_addr = "022575EC";
HPmax_addr = "022575E8";
MP_addr = "02257664";
MPmax_addr = "02257660";
HP = 1000;
HPmax = HP;
MP = 1000;
MPmax = MP;

--partnerHP_addr = "177D2215"; --rhain


-------------------------------------------------------------------------------------------------------
--FUNCTIONS
-------------------------------------------------------------------------------------------------------


--pickup items
function pickup()
keyboardPress(key.VK_X);
end

--select nearby monster
function target_monster()
keyboardPress(key.VK_SPACE);
end

--fight timer
function fight_timer()
keyboardPress(key.VK_SPACE);
end

--check if you have a target
function have_target()
if( 10 == 10 ) then
return true;
else
return false;
end



--updates variables from client
function update_var()
HP = memoryRead(proc, HP_addr);
HPmax = memoryRead(proc, HPmax_addr);
MP = memoryRead(proc, MP_addr);
MPmax = memoryRead(proc, MPmax_addr);
end

-- toggle can_heal to true, disable timer
function can_rest_timer()
unregisterTimer("can_rest_timer");
can_rest = true;
end

--rest until healed
function rest_heal()
if( can_rest == false ) then return; end

printf("Entering rest state\t%s\n", os.date("%X"));

keyboardPress(key.VK_T);

need_heal = true;
last_hp = HP;
while( need_heal ) do
yrest(100);

if( HP == HPmax and SP == SPmax ) then
need_heal = false;
end;

if( HP < last_hp ) then
print("Under attack! Exiting rest.");
can_rest = false;
registerTimer("can_rest_timer", 3000, can_rest_timer);
break;
else
last_hp = HP;
end;
end


--use hp potion
function hp_potion()
keyboardPress(key.VK_4);
end

--use mp potion
function mp_potion()
keyboardPress(key.VK_5)
end


--bot fight
function bot_fight()
registerTimer("fight_timer", 3000, fight_timer);
while(have_target()) do
if( HP < HP_potion) then hp_potion(); end
if( MP < MP_potion) then mp_potion(); end
if( math.random(100) > 50 ) then
keyboardPress(key.VK_1);
end
end
unregisterTimer("fight_timer");

for i = 0,8 do
pickup()
end

can_rest = false;
registerTimer("can_rest_timer", 3000, can_rest_timer);

end
-----------------------------------------------------------------------------------------------------------------
--MAIN BOT FUNCTIONS
-----------------------------------------------------------------------------------------------------------------


function main()
win = findWindow("Nostale");
local wx,wy,ww,wh = windowRect(win);

if( win == 0 ) then printf("Error! Could not locate Nostale window!\n"); return; end;
hdc = openDC(win)
proc = openProcess( findProcess("Nostale") );
attach(win);

registerTimer("update_vars", 100, update_vars);

while( 1 ) do
if( HP < HP_potion ) then hp_potion(); end
if( MP < MP_potion ) then mp_potion(); end
if( HP < HP_restatm and can_rest == true ) then rest_heal(); end
if( MP < MP_restatm and can_rest == true ) then rest_heal(); end

yrest(100);


target_monster();
yrest(200);
if( have_target() ) then
can_rest = fasle;
bot_fight(); end
can_rest = true;
end
pickup();
end

detach();
closeProcess(proc);
end

StartMacro(main)
This is the script i have come up with so far...I copied and edited parts from a fiesta bot script by elverion. I still have not tested the script because I am still lacking the target monster bit. I attached a photo of how the screen would look like when a monster is targeted can anyone teach me how to set the bot to target the monster?
Image

There are also a few bits of the script which I dont understand how they work
they are:
if( math.random(100) > 92 ) then
if( math.random(100) >= 50 ) then
<<what do these do?
keyboardHold(key_skill1);
yrest(50);
keyboardRelease(key_skill1);
else
keyboardHold(key_skill2);
yrest(50);
keyboardRelease(key_skill2);
end
end
and
for i = 0,8 do<<and this?
pickup();
yrest(50);
end
and
function have_target()
local r,g,b = getPixel(hdc, 540, 1); < this part

if( r >= 229 and r <= 240 and g >= 245 and g <= 255 and b >= 250 ) then<and this part
return true;
else
return false;
end
end
Sorry that I ask so many questions! Can someone please check my script and corrrect me at the places I have done wrong? Thank you!

EDIT: one more thingy...how do I write the script so that I can still bot while the main game window is minimized( so I can do other stuff while I'm botting ) Thx =P

Mesosmagnet
Posts: 37
Joined: Wed Apr 23, 2008 7:11 am

Re: [Request] Nostale Online Scripts -UPDATED-

#2 Post by Mesosmagnet » Thu Apr 24, 2008 12:33 am

I tested the script. and following the instructions of minimacro I corrected a few of them but I am stumped at this error
\nostale.lua:180: 'end' expected (to close 'function' at line 59) near '<eof>'
In my script the function at line 59 is this
function have_target()
if( 10 == 10 ) then
return true;
else
return false;
end
which I put in randomly so that I could test the script while waiting for a reply on how to get the proper have_target script. I dont know how to correct it :cry:

another problem :P (to bypass the above problem I just changed all have_target into 10 == 10
Error: Non-function type passed to startMacro(). Value is of type nil
from my script:
startMacro(main);

User avatar
Administrator
Site Admin
Posts: 5307
Joined: Sat Jan 05, 2008 4:21 pm

Re: [Request] Nostale Online Scripts -UPDATED-

#3 Post by Administrator » Thu Apr 24, 2008 12:52 pm

if( math.random(100) > 92 ) then
if( math.random(100) >= 50 ) then <<what do these do?
Math.random(max) generates a random number between 0 and max. So by using "if( math.random(100) > 92)", it will have a 92% chance of triggering. Since this isn't your desired behavior, just remove that and do it a simpler way.
for i = 0,8 do<<and this?
pickup();
yrest(50);
end
That's a for loop. It works as it reads... "for i = 0, until 8, i = i + 1". You may think of this as a sigma, if you are more familiar with math terms. Essentially, it will execute it's body (call pickup() and rest()) 8 (0 to 7) times.
local r,g,b = getPixel(hdc, 540, 1); < this part
Creates local variables r, g, and b, which will stand for red, green, and blue, respectively. It then assigns each of them to the 3 return values from getPixel(). getPixel() will read the color from the handle to device context (ie. the other game's window) at position (540, 1).
You can find more information in the online manual.
if( r >= 229 and r <= 240 and g >= 245 and g <= 255 and b >= 250 ) then<and this part
Checks if r, g, and b are within certain ranges. This in combination with the last snippet was used to read the color from the game's screen, and check if the HP bar was a reddish color (full).

EDIT: one more thingy...how do I write the script so that I can still bot while the main game window is minimized( so I can do other stuff while I'm botting ) Thx =P
It depends on how the game was designed. If it uses DirectInput rather than reading it's Win32 message queue, it won't be possible. Also, mouse input won't work. All you have to do to make this possible, though, is to attach input to the game window's input thread using the attach function.


\nostale.lua:180: 'end' expected (to close 'function' at line 59) near '<eof>'
You didn't properly close one of your functions.
function have_target()
if( 10 == 10 ) then
return true;
else
return false;
end
And this is the problem function. Both functions and if statements need an end, but you only have one. This is why spacing is important: it's much easier to see these problems.
function have_target()
if( 10 == 10 ) then
return true;
else
return false;
end
end
Fixed.

Error: Non-function type passed to startMacro(). Value is of type nil
This is because of the above error: you didn't close one of your functions, so everything below is within it. This means function main() is local to have_target(), and is therefor nil (does not exist) at global scope.

Mesosmagnet
Posts: 37
Joined: Wed Apr 23, 2008 7:11 am

Re: [Request] Nostale Online Scripts -UPDATED-

#4 Post by Mesosmagnet » Sat Apr 26, 2008 9:46 am

Sat Apr 26 22:19:06 2008 : WARNING: Failure reading memory from 0xAFEB28 at 0x80000000 in memoryReadInt(). Error code 998

Sat Apr 26 22:19:06 2008 : WARNING: Failure reading memory from 0xAFEB28 at 0x80000000 in memoryReadInt(). Error code 998

Sat Apr 26 22:19:06 2008 : WARNING: Failure reading memory from 0xAFEB28 at 0x80000000 in memoryReadInt(). Error code 998
does this error mean I need to use pointers? I have 4 addresses in my script HP, HPmax, MP, MPmax, but there are only 3 errors?
Attachments
nostale.lua
my problematic nostale bot (not working yet) if anyone would be kind enough to review the whole script and correct my errors and advise I would appreciate it alot.
(4.14 KiB) Downloaded 295 times

User avatar
Administrator
Site Admin
Posts: 5307
Joined: Sat Jan 05, 2008 4:21 pm

Re: [Request] Nostale Online Scripts -UPDATED-

#5 Post by Administrator » Sat Apr 26, 2008 10:46 am

System error code 998: Invalid access to memory location.

0xAFEB28 is a valid handle. 0x80000000 is (probably) and invalid memory location. In fact, addresses like 022575EC are probably dynamic, so you actually might need to use a pointer here.

I'd first suggest downloading the newer version of MicroMacro (better error handling and reporting -- it'll make figuring out bugs like this much easier). Also, you should change

Code: Select all

HP_addr		= "022575EC";
[/quote]
into
[code]
HP_addr		= 0x022575EC;
No real difference there, but it's the suggested way to do thing. It shouldn't be causing any error, but I guess it's possible that Lua is confusing the string for an integer, since there is lack of type support.

Mesosmagnet
Posts: 37
Joined: Wed Apr 23, 2008 7:11 am

Re: [Request] Nostale Online Scripts -UPDATED-

#6 Post by Mesosmagnet » Sat Apr 26, 2008 2:04 pm

Yeay Thx! But I guess I have alot more work to do, cuz the bot does nothing. :o

Basic Gameplay (Nostale)
1. SPACEBAR -selects nearby monster-
2. SPACEBAR/ "1" -attacks selected monster with normal hit/skill-
3. X -picks up nearby items-

in my main function after updating variables and checking if HP and MP is adequate to continue battle the function moves on to target_monster() function in which i set it to click the spacebar once. after that it makes sure I cant rest. then initiates the bot_fight() function which again checks whether HP and MP are proper for battle and then clicks the " 1 " key which in-game is set to the main attacking skill. and then goes to the pickup() function which I set to the " X " key. I dont get why the script does not carry out the actions stated. It jz stands there and I have to alt+tab out to the macro and then back to the main game-screen for it to target a monster, and alt+tab again to make it hit a monster. and it wont pick up items even if i alt+tab again.

more info:
" T " is set to rest
"0-9" can be set to skills and potions

I'm stumped! Using the old minimacro I was able to set the bot to kill monsters using

Code: Select all

REPEAT 0
  KEYPRESS VK_SPACE
  KEYPRESS VK_SPACE
  KEYPRESS X
  REST 200
LOOP
which is a very simple code which just hit monsters n picks up items. I tried to recreate the simple bot a few minutes ago because I was frustrated using the latest minimacro

Code: Select all

function main()
  attach( findWindow("Nostale"));
  
  while(1) do
    keyboardPress(key.VK_SPACE);
    keyboardPress(key.VK_SPACE);
    keyboardPress(key.VK_X);
  end

end
startMacro(main)
yet it still doesnt do a thing. I must be doing something seriously wrong because even a simple function like the above isnt working.

User avatar
Administrator
Site Admin
Posts: 5307
Joined: Sat Jan 05, 2008 4:21 pm

Re: [Request] Nostale Online Scripts -UPDATED-

#7 Post by Administrator » Sat Apr 26, 2008 3:07 pm

Try removing the attach() line; I doubt this will help, but it's worth a shot. Chances are, the game has some sort of protection, such as GameGuard. This needs to be disabled first.
I'm stumped! Using the old minimacro I was able to set the bot to kill monsters using
Was this code for the same game?

Mesosmagnet
Posts: 37
Joined: Wed Apr 23, 2008 7:11 am

Re: [Request] Nostale Online Scripts -UPDATED-

#8 Post by Mesosmagnet » Sat Apr 26, 2008 8:43 pm

yes both codes were for the same game. Nostale does not have any sort of gameguard or hacking protection yet. I could even attach WPE and cheat engines to it without any problem.
Btw...Thank you so much elverion. even if I failed in making a bot for nostale work I still learned a whole lot :D . I cant wait for the minimacro user guide ur working on! I'll keep trying though, hopefully I'll be able to figure out why the script doesnt work soon! Thx again!



EDIT
after removing the attach(win) the bot was able to select monsters and use potions when needed(wouldnt stop using potions though-not sure why) and couldnt pickup items. BUT still it was working. however I wasnt satisfied as I would still have to have the main game window selected for the bot to work. And it occurred to me...what if the name of the window i set the bot to attach to was not correct. SO I tried to run Nostale in windowed mode, i could have shouted for joy at that moment..as the window was actually named "Nomad of Silver Sprit - Nostale" and I was fooled the whole time thinking the window name shown at the taskbar was the actual name of the window. So now!...I only have a few errors to fix before my script is ready to use! YEAH!!!!! Thank you so so so much elverion!

User avatar
Administrator
Site Admin
Posts: 5307
Joined: Sat Jan 05, 2008 4:21 pm

Re: [Request] Nostale Online Scripts -UPDATED-

#9 Post by Administrator » Sat Apr 26, 2008 10:08 pm

use potions when needed(wouldnt stop using potions though-not sure why)
Can you be more specific? Would it just use, say, 15 potions at once, or would it continuously use potions for no reason what-so-ever? If the former, try setting a variable that will disable potion using for some amount of time. Just make a variable named "disablePotions" and set it to false. Now when you are about to use a potion, make sure disablePotions is false and set disablePotions to true, and set an automatic timer to trigger in 5 seconds (or, whatever the cooldown on the potions is). This automatic timer will 1) unregister itself, 2) set disablePotions back to false.

what if the name of the window i set the bot to attach to was not correct.
There's a number of functions and options available to you to help with this. findWindow() (and possibly derivatives) can make use of wildcard characters. So if the name of the window was (just an example here) "Nostale v1.23", you could findWindow("Nostale v?.*"); which would return the correct window in almost all cases.

You can also use foregroundWindow() which will return the window that currently has focus (is on top). You could, optionally, also make use of findWindowList(), which works very similarly to findWindow(), only it will return a table (array, dictionary, ...) which is populated by window window handles for all windows that fit the given mask.

Here's the example:

Code: Select all

myList = findWindowList("*notepad*");
for i = 1,#myList do
  printf("Found window %x [%s]\n", myList[i], getWindowName(myList[i]));
end
The above could would find all windows with "notepad" in their title, and print them all out like so:
Found window 12345678 [Untitled - Notepad]
Found window abcdef12 [Notepad - somescript.lua]
Using this, you could prompt the user to select a window in cases where more than window is returned. If you need more code on how to do this, just ask.



The important thing is that you found out where your bug is. I guess you should have been checking if win was nil or 0 not before calling attach(). attach() accepts nil or 0 (if I remember correctly...), and will act just like detach() if it receives this, so no error has been generated. The way attach() works is by directly stuffing the false keyboard input into the specified windows input queue...so if you do not have the correct window selected, it would not register at all.

Post Reply

Who is online

Users browsing this forum: No registered users and 7 guests