Jump to content
  • 0
Sign in to follow this  
Litro

3 questions regarding AnnieRuru scripts

Question

and I have no motivation to improve this script, I rather focus on battleground scripts

 

Im sad.. Hi Maam... its off topic but can i ask? well if my question is not proper please ignore its

 

1. well in anywhere i found you write about operation to make vvs like product with this

getitem2 1601, 1, 1, 0,0, 254, 0, getcharid(0) % pow(2,16), getcharid(0) / pow(2,16);
well im noobs really, if i were follow the script_commands.txt in the docs folder it will make me write more lines, but look you write it in just 1 line, but again im not uderstand what is the mean and purpose of
% pow(2,16)
2. About Private MvP Room, once again i forgot where i read it... you were say to change it to style Instancing, well im curious about that is 3 option for entering the room 1. Private Account 2.Party 3.Guild well hercules instance can make it for option 2&3 but the number 1? how you will make it.. ahh and the RAID Instance script you wrote time ago, if i was died 2 time in proces i was teleported to savepoint but i cant enter its again, like Endless tower...

 

can you kindly tell me, well i take a look into c++ program code still i dont understand it, well maybe im dummy but still i have a will to learn.. once again if you found it annoy you just ignore it

Edited by AnnieRuru
split topic from http://hercules.ws/board/topic/7014-

Share this post


Link to post
Share on other sites

7 answers to this question

Recommended Posts

  • 0

if you want to ask question just open a topic, no need to shy

 

all these questions has been asked before on eathena

if it isn't down right now, I can just give you the links

now I have to explain all over again

 


 

1.

no, my example follows exactly the script_commands.txt

there's no different with these 2 codes

prontera,155,184,5 script sample#1 100,{.@charid = getcharid(0);getitem2 1601, 1, 1, 0,0, 255, 0, .@charid % pow(2,16), .@charid / pow(2,16); // <-- minegetitem2 1601, 1, 1, 0,0, 255, 0, .@charid & 65535, .@charid >> 16; // <-- script commands.txtend;}

both sentence will gives you same item

.

.

ok how to explain this ...

 

if your character has char_id of 150000

when you click the above script and look in the SQL table

select nameid, card0, card1, card2, card3 from inventory where char_id = 150000;

return -> 1601,255,0,18928,2

 

the card2 field - 18928 is actually the remainder of 216 -> .@charid % pow(2,16)

the card3 field - 2 is actually the division of 216 -> .@charid / pow(2,16)

 

so my sentence is just exactly match what I said

 

you can also try this

prontera,157,184,5 script sample#2 100,{mes "enter a player name";next;input .@input$;if ( !query_sql( "select char_id, name from `char` where name = '"+ escape_sql( .@input$ ) +"'", .@cid, .@name$ ) ) { // if there is no row return from the querymes "player not found";close;}mes "you get "+ .@name$ +"'s Rod";getitem2 1601, 1, 1, 0,0, 255, 0, .@cid % pow(2,16), .@cid / pow(2,16);close;}

.

.

ok so now you understand that card2 is remainder and card3 is division of char_id

now why do script_commands.txt use binary operations

 

its because computer actually process faster with just 0 and 1

 

since we are small we were taught in mathematics, that numbers are in 1,2,3,4,5,6,7,8,9,10

this is actually base 10 operations

 

example ... every time you update your server using new client, you change PACKETVER 20140115

21040115

I can play it with the script like this

prontera,159,184,5 script sample#3 100,{mes PACKETVER +""; // return 20140115mes "Year = "+ PACKETVER / 10000; // return 2014mes "Month = "+ PACKETVER / 100 % 100; // return 1 ( 01, the zero is omitted )mes "Day = "+ PACKETVER % 100; // return 15close;}

.

.


 

Part 2 : here comes bit-shifting operations

 

I assumed that you already know what is binary numbers

 

let say, I give a number -> 10101010

if you divide 101010 by 1, you'll get 101010

if you divide 101010 by 10, you'll get 10101

if you divide 101010 by 100, you'll get 1010

if you divide 101010 by 1000, you'll get 101

if you divide 101010 by 10000, you'll get 10

if you divide 101010 by 100000, you'll get 1

prontera,161,184,5 script sample#4 100,{.@num = 101010;dispbottom .@num / 1 +""; // return 101010dispbottom .@num / 10 +""; // return 10101dispbottom .@num / 100 +""; // return 1010dispbottom .@num / 1000 +""; // return 101dispbottom .@num / 10000 +""; // return 10dispbottom .@num / 100000 +""; // return 1end;}

same as

if you divide 101010 by 100, you'll get 101010

if you divide 101010 by 101, you'll get 10101

if you divide 101010 by 102, you'll get 1010

if you divide 101010 by 103, you'll get 101

if you divide 101010 by 104, you'll get 10

if you divide 101010 by 105, you'll get 1

prontera,163,184,5 script sample#5 100,{.@num = 101010;dispbottom .@num / pow( 10, 0 )+""; // return 101010dispbottom .@num / pow( 10, 1 ) +""; // return 10101dispbottom .@num / pow( 10, 2 ) +""; // return 1010dispbottom .@num / pow( 10, 3 ) +""; // return 101dispbottom .@num / pow( 10, 4 ) +""; // return 10dispbottom .@num / pow( 10, 5 ) +""; // return 1end;}

-> 10101010 / 100 = 10101010

-> 10101010 / 101 = 1010110

-> 10101010 / 102 = 101010

-> 10101010 / 103 = 10110

-> 10101010 / 104 = 1010

-> 10101010 / 105 = 110

 

 

and now, let's say I give a number 1010102, which is 4210

prontera,166,184,5 script sample#6 100,{.@num = 42;dispbottom ( .@num >> 0 )+""; // return 42dispbottom ( .@num >> 1 )+""; // return 21dispbottom ( .@num >> 2 )+""; // return 10dispbottom ( .@num >> 3 )+""; // return 5dispbottom ( .@num >> 4 )+""; // return 2dispbottom ( .@num >> 5 )+""; // return 1end;}prontera,168,184,5 script sample#7 100,{.@num = 42;dispbottom .@num / pow( 2, 0 )+""; // return 42dispbottom .@num / pow( 2, 1 )+""; // return 21dispbottom .@num / pow( 2, 2 )+""; // return 10dispbottom .@num / pow( 2, 3 )+""; // return 5dispbottom .@num / pow( 2, 4 )+""; // return 2dispbottom .@num / pow( 2, 5 )+""; // return 1end;}

both scripts do the same

-> 42 / 20 = 42

-> 42 / 21 = 21

-> 42 / 22 = 10

-> 42 / 23 = 5

-> 42 / 24 = 2

-> 42 / 25 = 1

equal to

-> 1010102 / 102 = 1010102 = 4210

-> 1010102 / 102 = 101012 = 2110

-> 1010102 / 102 = 10102 = 1010

-> 1010102 / 102 = 1012 = 510

-> 1010102 / 102 = 102 = 210

-> 1010102 / 102 = 12 = 110

 

 

 

so, you'll noticed a pattern

in base 10, to decrease the digits by removing the last digit, you do

number / 10

Example => 10101010 / 10 = 1010110

in base 2, to decrease the last bit, you do right shift

number >> 1

Example => 1010102 >> 1 = 101012

=> 4210 >> 1 = 2110

 

its the same when opposite

in base 10, to increase the digits by adding zero at the back, you do

number * 10

Example => 10101010 * 10 = 101010010

in base 2, to increase the bits by adding zero, you do left shift

number << 1

Example => 1010102 << 1 = 10101002

=> 4210 << 1 = 8410

 

 

 

 

another example ...

if I want cut 10101010 into half

in base 10 (decimal) operations, we do

prontera,150,180,5 script sample#8 100,{.@num = 101010;dispbottom .@num / 1000 +""; // return 101dispbottom .@num % 1000 +""; // return 10 ( 010, zero is omitted )end;}

if I want to cut 1010102 into half

in base 2 (binary) operations, 2 ways in athena script engine

prontera,152,180,5 script sample#9 100,{.@num = 42;dispbottom .@num / pow(2,3) +""; // return 5 -> 101 base 2dispbottom .@num % pow(2,3) +""; // return 2 -> 010 base 2end;}

prontera,154,180,5 script sample#10 100,{.@num = 42;dispbottom ( .@num >> 3 )+""; // return 5 -> 101 base 2dispbottom ( .@num & ( (1<<3) -1 ) )+""; // return 2 -> 010 base 2end;}

although both script do the same thing,

but the computer will compute 2nd sample, which using binary shift faster

because computer prefer to calculate numbers in binary form

 

so revise back ...

getitem2 1601, 1, 1, 0,0, 255, 0, .@charid % pow(2,16), .@charid / pow(2,16); // <-- minegetitem2 1601, 1, 1, 0,0, 255, 0, .@charid & 65535, .@charid >> 16; // <-- script commands.txt

if you go look at sql-files

https://github.com/HerculesWS/Hercules/blob/master/sql-files/main.sql#L104

the card fields are using smallint, which is 216

since 150000 is higher than 32768, that's why it is being split

150000 % pow(2,16) as card2 field

150000 / pow(2,16) as card3 field

 

 

 

.... actually binary shifting operation has another uses ... to store more information using lesser variables ...

which is part 3 ... damn eathena forum down really wasting my time writing again

however this post takes me almost 1 hour to write so meh ... some other time then

Edited by AnnieRuru

Share this post


Link to post
Share on other sites
  • 0

ok, now explain the VVS and the elemental weapon part

 

they are store in card1 field

so just focus there

 

let's give an example

getitem2 1201, 1,1,0,0, 255, 1281, getcharid(0) % pow(2,16), getcharid(0) / pow(2,16);
1281 = you'll get Very Strong Ice elemental Knife
getitem2 1201, 1,1,0,0, 255, 2564, getcharid(0) % pow(2,16), getcharid(0) / pow(2,16);
2564 = you'll get Very Very Strong Wind elemental Knife

 

to get the VS or VVS or VVVS, it is a 1280*x

128? = Very Strong

256? = Very Very Strong

384? = Very Very Very Strong

 

to get elemental, it is a remainder of 10

???0 = neutral

???1 = Ice

???2 = Earth

???3 = Fire

???4 = Wind

 

something like this

prontera,156,185,6	script	ksdjhfksjf	100,{	.@card1 = getequipcardid( EQI_HAND_R, 1 );	switch ( .@card1 / 10 ) {	default: break;	case 128: dispbottom "Very Strong"; break;	case 256: dispbottom "Very Very Strong"; break;	case 384: dispbottom "Very Very Very Strong"; break;	}	if ( query_sql( "select name from `char` where char_id = "+( getequipcardid( EQI_HAND_R, 3 ) * pow(2,16) + getequipcardid( EQI_HAND_R, 2 ) ), .@name$ ) )//	if ( query_sql( "select name from `char` where char_id = "+( ( getequipcardid( EQI_HAND_R, 3 ) << 16 ) | getequipcardid( EQI_HAND_R, 2 ) ), .@name$ ) ) // both do the same		dispbottom .@name$;		switch ( .@card1 % 10 ) {	default: break;	case 1: dispbottom "Ice"; break;	case 2: dispbottom "Earth"; break;	case 3: dispbottom "Fire"; break;	case 4: dispbottom "Wind"; break;	}	dispbottom getequipname(EQI_HAND_R);	end;}
Edited by AnnieRuru

Share this post


Link to post
Share on other sites
  • 0

ok for the instance script

 

private mvp room issit ?

prontera,155,180,0	script	Rent a Room	123,{	mes "do you want to rent a room for yourself, party or guild ?";	for ( .@i = 1; .@i <= 3; .@i++ )		if ( has_instance2( "06guild_0"+ .@i ) >= 0 )			mes "You have rented a room for "+ .type$[.@i];	next;	.@s = select( "Party", "Guild", "Account" );	if ( has_instance2( "06guild_0"+ .@s ) >= 0 ) {		warp has_instance( "06guild_0"+ .@s ), 0,0;		end;	}	if ( !getcharid(.@s) ) {		mes "You must form a "+ .type$[.@s] +" to rent this room";		close;	}	if ( ( .@ins = instance_create( "Rent a Room", getcharid(.@s), .IOT[.@s] ) ) < 0 ) {		mes "error : "+ .@ins;		close;	}	if ( instance_attachmap( "06guild_0"+ .@s, .@ins, 1, .@s +"FYC"+ getcharid(.@s) ) == "" ) {		mes "error : 5";		instance_destroy .@ins;		close;	}	instance_set_timeout 30, 0, .@ins;	instance_init .@ins;	instance_attach .@ins;	warp has_instance( "06guild_0"+ .@s ), 0,0;	end;OnInit:	setarray .IOT[1], IOT_PARTY, IOT_GUILD, IOT_CHAR;	setarray .type$[1], "Party", "Guild", "Account";	end;}guild_vs2,49,49,0	script	FYC_instance_npc	100,{	if ( !mobcount( strcharinfo(3), instance_npcname( strnpcinfo(0) )+"::Ondead" ) )		monster has_instance( "guild_vs2" ), 49,49, "--ja--", 1002, 1, instance_npcname( strnpcinfo(0) )+"::Ondead";	end;Ondead:	dispbottom "oh yeah";	end;}guild_vs2	mapflag	nosave	SavePointguild_vs2	mapflag	nowarpguild_vs2	mapflag	nowarptoguild_vs2	mapflag	noteleportguild_vs2	mapflag	nomemoguild_vs2	mapflag	nopenaltyguild_vs2	mapflag	nobranchguild_vs2	mapflag	noicewall
IOT_CHAR actually attached to account ID

although the name has _CHAR but its not char_id ... hahaha dunno why Ind make it account-base anyway

but its quite comfortable to script using account_id

 


 

raid instance issit ?

http://herc.ws/board/topic/4652-raid-instances/?p=30524

ahh and the RAID Instance script you wrote time ago, if i was died 2 time in proces i was teleported to savepoint but i cant enter its again, like Endless tower...

that's because that map uses guild_vs2

die twice ... sounds like you enable pvp mapflag ?

cause I can't reproduce the problem right now on my latest hercules

Edited by AnnieRuru

Share this post


Link to post
Share on other sites
  • 0

now im confused Maam, how to say a lot of thanks ? :lv::thx:

well im not yet understand it now since im not fast learner and even i was re-reading it 3 times already :e8: , please be gentle maam  :sry: i still trying to diggest it slowly to make sure im not miss a bit of it..

Share this post


Link to post
Share on other sites
  • 0

 

that's because that map uses guild_vs2

 

die twice ... sounds like you enable pvp mapflag ?

 

cause I can't reproduce the problem right now on my latest hercules

 

i found the difference about 2 script you have maam and i think its about "has_instance" & "has_instance2", the *has_instance cant warp me back to my current dungeon if i were teleported to town

warp has_instance("guild_vs2"), 0,0;

and the next script i find that npc name was "Rent a Room"

if ( has_instance2( "guild_vs2" ) >= 0 ) {		warp has_instance( "guild_vs2" ), 0,0;		end;	}

it was intended or not i dont know its

if ( ( .@ins = instance_create( "Dungeon event", getcharid(1), IOT_PARTY ) ) < 0 ) {		mes "error : "+ .@ins;		close;	}

in the game the script work as intended and the console throw error

[Error]: instance_create: party 0 not found for instance 'Rent a Room'.[Error]: buildin_instance_create: Invalid party ID [-2].

Share this post


Link to post
Share on other sites
  • 0

there is a difference for *has_instance and *has_instance2

has_instance return the map names, so has to check with 'if ( has_instance( "guild_vs2" ) == "" )'

has_instance2 return the instance ID, so has to check with 'if ( has_instance2( "guild_vs2" ) == -1 )'

 

and if there's an instance running for the player,

at the bottom right down corner there should be a small window indicating instance were running ...

 

I believe for the Raid instance, just add these line

if ( has_instance2( "guild_vs2" ) >= 0 ) {		warp has_instance( "guild_vs2" ), 0,0;		end;	}
and you can go in again ... haven't test

.

.

.

in the game the script work as intended and the console throw error

ouch !

I forgot a check if there is no party, you can't rent the room for party, same for guild

fix the previous script

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.