Jump to content
  • 0

comment on my 1st script ?


Ajjwidjdneidjenw

Question


  • Group:  Members
  • Topic Count:  15
  • Topics Per Day:  0.00
  • Content Count:  161
  • Reputation:   31
  • Joined:  12/06/11
  • Last Seen:  

* entirely off topic post

darned, got beaten by experience XD (Could've done it that way yeah.).

hey, tbh I've started scripting in April(an easter event was my first script, yay goto's labels and overall poorly coded), gotta give me some credit :P.

Found it, one of my first scripts..

//Made by Jeroen
//Made using the rachel sanc quest as layout
moscovia.gat,225,191,5    script    Easter Bunny    1322,{

   if (EB_COMPLETE == 1) {
   mes "[bunny]";
   mes "Thank you so much for returning my eggs!";
   close;
   end;
   }

   mes "[bunny]";
   mes "Hello!";
   mes "I am the easter bunny!";
   mes "I know my appearance is a little bit strange but that's because I lost my Eggs!";
   mes "If you manage to find all my eggs I wil give you a reward!";
   next;


   if ((RED_EGG == 1) && (BLUE_EGG == 1) && (YELlOW_EGG == 1) && (GREEN_EGG == 1) && (PURPLE_EGG == 1) && (BLACK_EGG == 1) && (GOLD_EGG == 1)) {
   mes "[bunny]";
   mes "Oh! I see you have my eggs!";
   mes "Would you like to receive your items now ?";
   next;
   menu "Redeem Item",-,"Cancel",EB_END;
   }
   Else {
   mes "[bunny]";
   mes "I think I lost my eggs while traveling through the following locations:";
   mes "Poring heaven, The ruins of Morocc, The new worlds camp,in the realm of anubises,";
   mes "In a Toy Factory, In a lair of a 3 headed dragon and under a gaint tree in amatsu";
   next;
   mes "[bunny]";
   mes "Please help me find them.";
   set EB_START,1;
   close;
   end;
   }

   if(checkweight(607,1) == 0){
       mes "[bunny]";
       mes "You are carrying too many items!";
       mes "Please come back later!";
       close;
   }

   mes "[bunny]";
   mes "Here we go!";
   Next;

       mes "[bunny]";
       mes "What will it be?! Time to find out!";
       Next;
       set .@bonus_ticket,rand(50);
       if (.@bonus_ticket == 50) getitem 5378,1;    // Bunny top hat 2% chance
       else if (.@bonus_ticket > 21 && .@bonus_ticket < 44) getitem 7619,1;    //Enriched Elunium 22%
       else if (.@bonus_ticket > 0 && .@bonus_ticket < 20) getitem 14208,1; //Field Manual Box 38%
       else getitem 13914,1; // Party Assumptio scrollbox 38%
       next;
       mes "[Lottery Machine]";
       mes "Congratulations! Come back soon!";
       set #EB_COMPLETE,1;
       set EB_START,0;
       close;
       end;

EB_END:
   mes "[bunny]";
   mes "Come back soon!";
   close;
   end;

}

pay_fild04,146,107,3    script    RedEgg#Red    -1,3,3,{
   end;

OnTouch:
if (RED_EGG == 1)
   end;

   if (EB_START == 1) {
   mes "["+strcharinfo(0)+"]";
   mes "I can see a red egg up in that tree";
   mes "if only I had some sort of ^6B8E23Strong Branch^000000";
   next;
   if (countitem(7203) > 0) {
   mes "["+strcharinfo(0)+"]";
   mes "Oh wait! I do have some!";
   mes "Lets try to get it out!";
   next;
   set .@red_eggget,rand(1,20);
   if (.@red_eggget < 3) {
   mes "["+strcharinfo(0)+"]";
   mes "Yes! I got the Red egg!";
   set RED_EGG,1;
   close;
   }
       else {
       delitem 7203,1; //Strong Branch
       Mes "^6B8E23The Strong Branch broke in the attempt^000000";
       close;
       }
   }
   else {
   mes "["+strcharinfo(0)+"]";
   mes "I better start collecting some";
   close;
   }
}
}

mid_camp,227,235,3    script    BlueEgg#Blue    -1,3,3,{
   end;

OnTouch:
if (BLUE_EGG == 1)
   end;

   if (EB_START == 1) {
   mes "["+strcharinfo(0)+"]";
   mes "Ah!! I see a blue egg!";
   mes "But it's stuck in this triangular shape thing.";
   mes "I wonder if I can get it out.";
   next;
   mes "^0003FF*clink* *Clink* *CLANG CLANG*^000000";
   next;
   mes "["+strcharinfo(0)+"]";
   mes "By the power of all Whitesmiths!!!!";
   mes "I will pull you out!";
   next;
   mes "^0003FF*BANG* *BANG* *BANG*^000000";
   specialeffect2 EF_Blessing;
   next;
   specialeffect2 EF_OVERTHRUST;
   next;
   mes "["+strcharinfo(0)+"]";
   mes "I got the blue egg!";
   set BLUE_EGG,1;
   close;
   }
}

moc_ruins,59,161,3    script    YellowEgg#Yellow    -1,3,3,{
   end;

OnTouch:
if (YELLOW_EGG == 1)
   end;

   if (EB_START == 1) {
   mes "[????]";
   mes "hehehehe.....";
   mes "Are you looking for this?";
   next;
   mes "["+strcharinfo(0)+"]";
   mes "Yes! But how did you know?";
   mes "and where did you get it from?";
   next;
   mes "[Kafra Employee]";
   mes "You may have it under one condittion.";
   mes "You will need to answer the following questions";
   mes "Are you ready?";
   switch(select("Yes!?:...No! I don't want to.")) {
   next;
   case 1:
       mes "[Kafra employee]";
       mes "Well then,";
       mes "let's begin.";
       next;
       mes "[Kafra employee]";
       mes "What day is easter Celebrated?";
       next;
       if (select("Sunday:Teusday:Friday:Saturday") == 1)
       set .@yellow_q,.@yellow_q+10;
       mes "[Kafra employee]";
       mes "Why do we have eggs at Easter?";
       next;
       if (select("Because they are yummy:They resemble Rebirth:Because.. just give me the egg") == 2)
       set .@yellow_q,.@yellow_q+10;
       mes "[Kafra employee]";
       mes "Which came first?";
       next;
       if (select("The chicken:The egg:None of Both:Jero") == 3)
       set .@yellow_q,.@yellow_q+10;
       mes "[Kafra employee]";
       mes "A female rabbit is called a...?";
       next;
       if (select("Doe:Cow:chicken:JC") == 1)
       set .@yellow_q,.@yellow_q+10;
       mes "[Kafra employee]";
       mes "What kind of tail does the easter bunny assumed to have?";
       next;
       if (select("Cutton Tail:Chocolate Tail:Liquor Tail:Bunny's have tails?") == 1)
       set .@yellow_q,.@yellow_q+10;
       mes "[Kafra employee]";
       mes "Okay, this is the end of the test!";
       next;
       if (.@yellow_q > 39) {
       mes "[Kafra employee]";
       set YELlOW_EGG,1;
       mes "Fine you can have the egg";
       next;
       mes "You got the Yellow egg!";
       close;
       }
       else {
       mes "[Kafra employee]";
       mes "I'm sorry you failed";
       mes "Please try agian!";
       close; }
   case 2:
   mes "[Kafra employee]";
   mes "come back later!";
   close;
   }
}
}

in_sphinx4,25,214,3    script    GreenEgg#Green    -1,3,3,{
   end;

OnTouch:
if (GREEN_EGG == 1)
   end;

if ((TABLET_A == 1) && (TABLET_B == 1) && (TABLET_C == 1) && (TABLET_D == 1) && (TABLET_E == 1)) {
   mes "You inserted all of the tablets into the wall";
   mes "A hidden hatch opened,";
   mes "and you received the green egg!";
   set GREEN_EGG,1;
   set TABLET_A,0;
   set TABLET_B,0;
   set TABLET_C,0;
   set TABLET_D,0;
   set TABLET_E,0;
   close;
   }
if (TABLET_A == 1)
   end;

   if (EB_START == 1) {
   mes "["+strcharinfo(0)+"]";
   mes "Hm... there is a strange writing on the wall";
   next;
   mes "^0003FFIn order to get the Green egg";
   mes "You will need to find 5 Tablets";
   mes "You can find them on your minimap as you go along";
   mes "After you got all 5 Tablet, return to this point^000000";
   next;
   viewpoint 1,20,230,4,0x00FF00;
   mes "^0003FF You got Tablet A!";
   set TABLET_A,1;
   close;
   }
}

in_sphinx4,20,230,3    script    TABLET_B#Green    -1,3,3,{
   end;

OnTouch:
if (GREEN_EGG == 1)
   end;

if (TABLET_B == 1)
   end;

if (TABLET_A == 1) {
   mes "You have found tablet B!";
   set TABLET_B,1;
   viewpoint 1,16,7,4,0x00FF00;
   close;
   }
}

in_sphinx4,16,15,3    script    TABLET_C#Green    -1,3,3,{
   end;

OnTouch:
if (GREEN_EGG == 1)
   end;

if (TABLET_C == 1)
   end;

if (TABLET_A == 1) {
   mes "You have found tablet C!";
   set TABLET_C,1;
   viewpoint 1,119,122,4,0x00FF00;
   close;
   }
}

in_sphinx4,119,122,3    script    TABLET_D#Green    -1,3,3,{
   end;

OnTouch:
if (GREEN_EGG == 1)
   end;

if (TABLET_D == 1)
   end;

if (TABLET_A == 1) {
   mes "You have found tablet D!";
   set TABLET_D,1;
   viewpoint 1,229,55,4,0x00FF00;
   close;
   }
}

in_sphinx4,229,55,3    script    TABLET_E#Green    -1,3,3,{
   end;

OnTouch:
if (GREEN_EGG == 1)
   end;

if (TABLET_E == 1)
   end;

if (TABLET_A == 1) {
   mes "You have found tablet E!";
   set TABLET_E,1;
   close;
   }
}
amatsu,263,195,3    script    Angel Rabbit#Purple    1063,3,3,{

if (PURPLE_EGG == 1)
   end;

   if (EB_START == 1) {
   mes "There's a rabbit here, guarding a purple egg.";
   mes "What will you do to take the egg?";
   next;
   switch(select("Pet the rabbit:Kick the rabbit:Eat the rabbit:just walk away")) {
       case 1: {
       mes "you attempted to pet the rabbit";
       mes "The rabbit got scared and bit you.";
       mes "in the mean time you managed t take the egg";
       percentheal -60,0;
       set PURPLE_EGG,1;
       close;
       }
       break;
       case 2:  {
       mes "You kicked the rabbit, sending it flying";
       mes "in the meantime you grab the egg, it is now yours.";
       set PURPLE_EGG,1;
       close;
       }
       break;
       case 3: {
       mes "you started to boil a hot soup and put the rabbit in the bowl.";
       mes "hm... Rabbit stew.";
       mes "you restored all your energy, and you got the purple egg.";
       percentheal 100,100;
       set PURPLE_EGG,1;
       close;
       }
       break;
       case 4:
       mes "you ran away";
       close;
   }
}
}

mosk_dun03,222,229,3    script    BLACK_EGG#BLACK    -1,3,3,{
   end;

OnTouch:
If (BLACK_EGG == 1)
end;    

if (EB_START == 1) {
   mes "You see a black egg in between the pile of skulls";
   mes "you will need about 50 holy waters, to clear the way to the black egg.";
   next;
   if (countitem(523) > 49) {
       mes "You have enough holy waters to clear the way";
       mes "Do you want to use them?";
       next;
       menu "yes",-,"no",BA_END;
       mes "You cleared your way and got the black egg!";
       delitem 523,50; //Holywater
       set BLACK_EGG,1;
       close;

BA_END:
Close;
       }

   mes "Better start get some holy waters!";
   close;
   }
}

xmas_dun01,205,27,3    script    Chepet#GOLD    1250,3,3,{

if (GOLD_EGG == 1)
end;
   if ((countitem(7035) > 0) && (countitem(969) > 0) && (countitem(7053) > 99)) {
   mes "[Chepet]";
   mes "I see you have the items!";
   mes "Do you want to make a trade?";
   menu "yes",-,"no",GO_END;
   next;
   mes "Thank you!";
   delitem 7035,1;
   delitem 969,1;
   delitem 7053,100;
   set GOLD_EGG,1;
   close;
   }
   mes "[Chepet]";
   mes "hello! I see you are";
   mes "interested in this golden egg I found";
   next;
   mes "[Chepet]";
   mes "How about a little trade?";
   mes "I want the following items:";
   mes "^0003FF1 Match stick";
   mes "1 Gold";
   mes "and 100 Cyfar";
   next;
   mes "[Chepet]";
   mes "Please bring them to me";
   close;

GO_END:
close;

}

This doesn't belong here though, mind if we continue this in a PM :P?

Edited by AnnieRuru
split topic from topic ID 74909
Link to comment
Share on other sites

Recommended Posts


  • Group:  Members
  • Topic Count:  18
  • Topics Per Day:  0.00
  • Content Count:  2044
  • Reputation:   682
  • Joined:  10/09/12
  • Last Seen:  

its fine

sometimes its even better to show your script to the community and we'll help you improve your scripting skills

let's see ...

    set GREEN_EGG,1;
   set TABLET_A,0;
   set TABLET_B,0;
   set TABLET_C,0;
   set TABLET_D,0;
   set TABLET_E,0;

I'm quite sure you know how to do bitmask ?

TABLET = TABLET | 1 << 1;

the way you are doing is wasting permanent variable space, I guess you know it by now ?

if ((RED_EGG == 1) && (BLUE_EGG == 1) && (YELlOW_EGG == 1) && (GREEN_EGG == 1) && (PURPLE_EGG == 1) && (BLACK_EGG == 1) && (GOLD_EGG == 1)) {

same here, I guess

http://www.eathena.ws/board/index.php?showtopic=153708

http://www.eathena.ws/board/index.php?showtopic=162523&hl=

http://www.eathena.ws/board/index.php?s=&showtopic=154325&view=findpost&p=850808

other than wasting variable space, its somehow a very nicely written functionality script o.o

Edited by AnnieRuru
  • Upvote 1
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  0
  • Topics Per Day:  0
  • Content Count:  205
  • Reputation:   19
  • Joined:  10/12/12
  • Last Seen:  

What's up with bitmasks? Why wasting a spot on heap to operate something binary when actually is the same thing?

The variable is stored in a xBit register, and so it happens when you operate with bitmasks. The thing is actually the same, just without any shift or check operation.

@Annie: You are a bitmasks-addicted, you should try to program on assembly :P

EDIT: I believe this thread can still be up without getting on PMs, it can help many people to improve a lot as things has started to be shown.

Can also be a chance for newbie scripters to learn bitmasks, as the argument has been introduced here.

Just my belief :P

Edited by Ryokem
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  15
  • Topics Per Day:  0.00
  • Content Count:  161
  • Reputation:   31
  • Joined:  12/06/11
  • Last Seen:  

Lol, if you read my post, that is actually ones of my first script ever written a long while ago, would I do it agian I wouldn't have done it this way. That's what I meant :P.

if I can say it myself, this entire script was/is a mess back when I made it, I can do it so much better now in different aspects. Thing is, I cannot really show some of my current stuff, as they're more private towards my own server / Other server I dev for. I'll have to create something specifically for rAthena, or write something simmiliar to what I have done in in the past.

it came from this topic, what I meant with the 'continue in pm' would basically be a discussion about scripting, as we had some fun in the previously stated topic.

@annie

Darnit, you made me feel like a newbie XD, *protects self.

Edited by garet999
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  18
  • Topics Per Day:  0.00
  • Content Count:  2044
  • Reputation:   682
  • Joined:  10/09/12
  • Last Seen:  

@garet999

so I guess you've learned it then xD

and ... ops ?

but your 1st script like this ... even much better than my 1st script >_< ...

my 1st script is even worst than the script generated by this program

I still remember when I was a newbie scripter, I actually learned from script generator 1st lol

@Ryokem

hmm ... so what's your suggestion on improving about variable saving ?

I do understand what you are saying if it is saving in temporary player variable ...

as we can practically have unlimited temporary player variable until server runs out of memory

but its not the case when dealing with permanent player variable because we currently have a hard-coded limit of 256 atm

you mean, your other emulator actually allows to save variables that way ?

EDIT: I believe this thread can still be up without getting on PMs, it can help many people to improve a lot as things has started to be shown.

Can also be a chance for newbie scripters to learn bitmasks, as the argument has been introduced here.

Just my belief :P

same feeling here o.o
you should try to program on assembly
hmm I never actually tries to code something outside eathena/rathena

any example or external links that I can refer on ?

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  15
  • Topics Per Day:  0.00
  • Content Count:  161
  • Reputation:   31
  • Joined:  12/06/11
  • Last Seen:  

Well its not really my first, my first ones were really the item scripts and such. Trust me, I've spend a whole bunch of hours on that script above^, and I attempted a few other scripts. This one was really my own.

(except for the item rewarding part, copied that from the Rachel Sanctuary quest, and modified that.).

Looking back at it makes me want to start writing a script for Christmas already, I should start brainstorming.

anyway 2 am here, gotta go, college tommorow and all. I'll be looking forward to our next 'script showdown,'

Edited by garet999
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  18
  • Topics Per Day:  0.00
  • Content Count:  2044
  • Reputation:   682
  • Joined:  10/09/12
  • Last Seen:  

Looking back at it makes me want to start writing a script for Christmas already, I should start brainstorming.

suggestion :

so you also know how to write using Quest Log system ?

http://www.eathena.ws/board/index.php?s=&showtopic=269839&view=findpost&p=1481667

somehow I feel using quest log is even better than using bitmask here o.o

has better GUI interface ... etc ...

well of course you don't have to tell your exact idea about that script

but if you want to improve your techniques, we can share XD

Edited by AnnieRuru
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  31
  • Topics Per Day:  0.01
  • Content Count:  666
  • Reputation:   93
  • Joined:  04/27/12
  • Last Seen:  

I personally, don't like the Quest Log lol... I despise the GUI !! I perfer my @quest implemention lol. Though... it is harder to use than the Quest Log T.T; I gotta hand script all details of my quests into it, but it's fine, kinda like a HELP i'm lost give me a walkthrough.

Back on topic now.... This script is well written for a first script, but as Annie said, it does use quite a bit of perm-variables to get the job done. My suggestion would be to use: ' .variables ' for all the sub ones until the quest/event is complete then use, your ' #variable ' as the only perm-var. This would save resources.

Example:

Instead of:

set RED_EGG,1;

You can use:

setd "."+"RED_EGG"+ getcharid(3) +"",1;

Granted, it looks messier, it does eliminate the need of perm-vars until the script is actually done. Additionally, you can set them into an array using this method, to effectively eliminate the need of making different named variables.

setd "."+"RED_EGG"+ getcharid(0) +"[0]",1;
setd "."+"RED_EGG"+ getcharid(0) +"[1]",1;

Lastly I don't think anyone noticed this but your script does have a pretty bad typo, preventing the quest from completing...

if (EB_COMPLETE == 1) {
mes "[bunny]";
mes "Thank you so much for returning my eggs!";
close;
end;
}

&&

mes "[Lottery Machine]";
mes "Congratulations! Come back soon!";
set #EB_COMPLETE,1;
set EB_START,0;
close;
end;

Right now it's setting: ' #EB_COMPLETE ' to 1. But is checking for: ' EB_COMPLETE '. You need either change the other one to a #var as well, or erase the ' # ' in the first var lol. Or they will be able to continually do the quest as far as I see it.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  18
  • Topics Per Day:  0.00
  • Content Count:  2044
  • Reputation:   682
  • Joined:  10/09/12
  • Last Seen:  

My suggestion would be to use: ' .variables ' for all the sub ones until the quest/event is complete then use, your ' #variable ' as the only perm-var. This would save resources.

Example:

Instead of:

set RED_EGG,1;

You can use:

setd "."+"RED_EGG"+ getcharid(3) +"",1;

Granted, it looks messier, it does eliminate the need of perm-vars until the script is actually done. Additionally, you can set them into an array using this method, to effectively eliminate the need of making different named variables.

setd "."+"RED_EGG"+ getcharid(0) +"[0]",1;
setd "."+"RED_EGG"+ getcharid(0) +"[1]",1;

... what kind of trick is this o.O

if a server crash, every player will starts to complain !

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  31
  • Topics Per Day:  0.01
  • Content Count:  666
  • Reputation:   93
  • Joined:  04/27/12
  • Last Seen:  

Well, for one, I usually write my scripts under the assumption that the server wont crash (However I do know that it is a possibility). But if were going to assume that the server IS goign to crash... then yes, I would agree, bitmask would be the way to go. Or even just using a string var.

Instead of:

if ((RED_EGG == 1) && (BLUE_EGG == 1) && (YELLOW_EGG == 1) && (GREEN_EGG == 1) && (PURPLE_EGG == 1) && (BLACK_EGG == 1) && (GOLD_EGG == 1)) {

We can use:

if( compare(""+EGG_FOUND+"","1234567") ) { do this; } //Were not including the "0" in this since we only need to check for numbers 1-7

And to set this variable, we can do this:

if( EGG_FOUND$ == "" ){set EGG_FOUND$,"0";}
set EGG_FOUND$, ""+insertchar(EGG_FOUND$,""+getstrlen(EGG_FOUND$),getstrlen(EGG_FOUND$));

The only issue with this is the way we check to see which one is done. Which is why we can either go the easy route, and make them have to find each egg in order.

OR we can hardcode each EGG's script to have a certain number for the egg. I'll use the existing ' if () ' command as an example:

if( EGG_FOUND$ == "" ){set EGG_FOUND$,"0";}
set EGG_FOUND$, ""+insertchar(EGG_FOUND$,""+1,2); //RED_EGG = 1, BLUE_EGG= 2, YELLOW_EGG = 3
set EGG_FOUND$, ""+insertchar(EGG_FOUND$,""+2,3);
set EGG_FOUND$, ""+insertchar(EGG_FOUND$,""+3,4);
//This would display: "0123"
dispbottom EGG_FOUND$;

Again, I know this just over-complicates things, but the point to was to comment on his script, and as all if not most of us scripters are, we like to give example to further their abilities. So even if this method is un-ethical, it is a new technique lol.

Edited by GmOcean
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  9
  • Topics Per Day:  0.00
  • Content Count:  379
  • Reputation:   304
  • Joined:  11/10/11
  • Last Seen:  

I want to participate :D

@garet999

Good job for one of your first script.

Just something, this part of code will never be executed.

        set .@bonus_ticket,rand(50);
       if (.@bonus_ticket == 50) getitem 5378,1;    // Bunny top hat 2% chance

rand(50) giver a result in range 0-49.

@Ryokem

No, I agree again with Annie.

We are limited with PC variables and have to use some stuff to don't reach the server limit. We don't care about how it's stored in the DB (and even it's always smaller to store 30 booleans into one INT (4 bytes) instead of having 30 INT with values 0-1 (4*30 bytes) ).

@GmOcean

I have to agree with Annie, using your getd(".") stuff will be reset on each reloadscript, reboot, crash and pollute the script buffer :(

Edit: Yeah string can be used too :)

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  15
  • Topics Per Day:  0.00
  • Content Count:  161
  • Reputation:   31
  • Joined:  12/06/11
  • Last Seen:  

I'll try to create a 'simple' public script later, so I can show you guys where I started, and where I am right now :P.

Edit: can't think of anything ,and I gtg to college.

Ideas anyone?

Might as well post one of my other scripts. This one is fairly simple

//PvP script V.1.5
//By Jero
//1.1, added a dual log check.
//1.2, added a PvP NPC
//= Version 1.3 Optimised script preformance.
//= Version 1.4 Added MAC check instead of IP
//= Version 1.5 Cleaned up the code
//=================================NPC=================================
prontera,148,189,6	script	PvP warper#01::SPVP	59,{
	mes "[PvP warper]";
	mes "What PvP room would you like to enter?";
	if (select("Normal PvP [^FF0000"+getmapusers("06guild_01")+"^000000]:"+
	"No item PvP [^FF0000"+getmapusers("06guild_02")+"^000000]:"+
	"GvG Room [^FF0000"+getmapusers("06guild_03")+"^000000]:"+
	"No, I'm not a violent person") == 4) close;
	query_sql "select `last_mac` from `login` where `account_id`='"+getcharid(3)+"'",.@PVPUIP$;
	If (getd("$@SPVP" + .@PVPUIP$)) {
		Mes "Dual Log detected, Access not permitted.";
		close;
	}
	callfunc "disppvp";
	setd ("$@SPVP" + .@PVPUIP$), 1;
	warp "06guild_0"+@menu,0,0;
	close;

//===============================Other Events===========================================

OnPCDieEvent:
if (strcharinfo(3) == "06guild_01" || strcharinfo(3) == "06guild_02" || strcharinfo(3) == "06guild_03") {
	query_sql "select `last_mac` from `login` where `account_id`='"+getcharid(3)+"'",.@PVPUIP$;
	setd ("$@SPVP" + .@PVPUIP$), 0;
	end;
}

OnPCLogoutEvent:
if (strcharinfo(3) == "06guild_01" || strcharinfo(3) == "06guild_02"  || strcharinfo(3) == "06guild_03" ) {
	query_sql "select `last_mac` from `login` where `account_id`='"+getcharid(3)+"'",.@PVPUIP$;
	setd ("$@SPVP" + .@PVPUIP$), 0;
	end;
}
}



//================================Arena NPC===========================================
06guild_02,50,4,4	script	Arena Guardian#01::AGUARD	416,{
mes "[Arena Guardian]";
mes "Do you wish to leave the arena?";
next;
if (select("Yes Please let me out:No way!") == 2) close;
query_sql "select `last_mac` from `login` where `account_id`='"+getcharid(3)+"'",.@PVPUIP$;
getmapxy(.@m$,.@x,.@y,0);
if (getmapusers(.@m$) != 1) {
	set .@AGRDPW, rand(9000000, 10000000);
	mes "[Arena Guardian]";
	mes "please type in the following number " +.@AGRDPW;
	next;
	input .@AGRDPW2;
	if(.@AGRDPW != .@AGRDPW2) {
		mes "Incorrect password, please try again.";
		close;
	}
}
mes "Thank you for participating!";
mes "I hope to see you again soon!";
next;
setd ("$@SPVP" + .@PVPUIP$), 0;
warp "SavePoint",0,0;
end;
}

//================================Mapflags============================================
06guild_02	mapflag	nomemo
06guild_02	mapflag	noteleport
06guild_02	mapflag	nopenalty
06guild_02	mapflag	nowarp
06guild_02	mapflag	nowarpto
06guild_02	mapflag	noreturn
06guild_02	mapflag	nobranch
06guild_02	mapflag	nosave
06guild_02	mapflag	pvp_noguild
06guild_02	mapflag	nogo
06guild_02	mapflag	pvp
06guild_02	mapflag	restricted	8
//normal
06guild_01	mapflag	nomemo
06guild_01	mapflag	noteleport
06guild_01	mapflag	nopenalty
06guild_01	mapflag	nowarp
06guild_01	mapflag	nowarpto
06guild_01	mapflag	noreturn
06guild_01	mapflag	nobranch
06guild_01	mapflag	nosave
06guild_01	mapflag	pvp_noguild
06guild_01	mapflag	nogo
06guild_01	mapflag	pvp
//GVG
06guild_03	mapflag	nomemo
06guild_03	mapflag	noteleport
06guild_03	mapflag	nopenalty
06guild_03	mapflag	nowarp
06guild_03	mapflag	nowarpto
06guild_03	mapflag	noreturn
06guild_03	mapflag	nobranch
06guild_03	mapflag	nosave
06guild_03	mapflag	pvp_noguild
06guild_03	mapflag	nogo
06guild_03	mapflag	gvg


//================================NPC Duplicates=======================================
morocc,170,89,3	duplicate(SPVP)	PvP warper#02	56
geffen,127,66,3	duplicate(SPVP)	PvP warper#03	56
payon,167,227,3	duplicate(SPVP)	PvP warper#04	56
alberta,200,148,3	duplicate(SPVP)	PvP warper#05	56
aldebaran,134,115,5	duplicate(SPVP)	PvP warper#06	56
comodo,185,156,5	duplicate(SPVP)	PvP warper#07	56
gonryun,163,126,3	duplicate(SPVP)	PvP warper#08	56
louyang,210,101,5	duplicate(SPVP)	PvP warper#09	56
hugel,106,156,4	duplicate(SPVP)	PvP warper#10	56
dicastes01,188,181,4	duplicate(SPVP)	PvP warper#11	56

//==============================Guard Duplications.=====================================
06guild_02,4,50,4	duplicate(AGUARD)	Arena Guardian#02	416
06guild_02,50,95,4	duplicate(AGUARD)	Arena Guardian#03	416
06guild_02,97,50,4	duplicate(AGUARD)	Arena Guardian#04	416
06guild_01,4,50,4	duplicate(AGUARD)	Arena Guardian#05	416
06guild_01,50,95,4	duplicate(AGUARD)	Arena Guardian#06	416
06guild_01,97,50,4	duplicate(AGUARD)	Arena Guardian#07	416
06guild_03,4,50,4	duplicate(AGUARD)	Arena Guardian#08	416
06guild_03,50,95,4	duplicate(AGUARD)	Arena Guardian#09	416
06guild_03,97,50,4	duplicate(AGUARD)	Arena Guardian#10	416
06guild_01,50,4,4	duplicate(AGUARD)	Arena Guardian#11	416
06guild_03,50,4,4	duplicate(AGUARD)	Arena Guardian#12	416

function	script	disppvp	{
sc_end sc_gospel;
sc_end sc_poembragi;
sc_end sc_service4u;
sc_end SC_APPLEIDUN;
sc_end sc_kyrie;
sc_end SC_ASSUMPTIO;
sc_end SC_QUAGMIRE;
sc_end SC_MINDBREAKER;
sc_end SC_READING_SB;
sc_end SC_KAUPE;
sc_end SC_KAAHI;
sc_end SC_KAIZEL;
sc_end SC_ADRENALINE2;
return;
}

Edited by garet999
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  0
  • Topics Per Day:  0
  • Content Count:  205
  • Reputation:   19
  • Joined:  10/12/12
  • Last Seen:  

@Ryokem

No, I agree again with Annie.

We are limited with PC variables and have to use some stuff to don't reach the server limit. We don't care about how it's stored in the DB (and even it's always smaller to store 30 booleans into one INT (4 bytes) instead of having 30 INT with values 0-1 (4*30 bytes) ).

Not really as the space they will placed in is different, unless rAthena didn't really changed it (I just supposed it's like all "normal" IPL's). And as I said before, both ways are correct, but I'd prefer not to use the heap to compute bitmasks, when I can just store values, especially if there can be future updates about the script. Also, are you sure that bitmasks actually set the variable as boolean? I believe that even if it has boolean properties, it's considered as integer, so the memory used won't change, unless you use just one variable and make correspond every bit to a variable value. But the same you can do with integers as well.

you should try to program on assembly
hmm I never actually tries to code something outside eathena/rathena

any example or external links that I can refer on ?

Assembly language (wikipedia)

Based on registers and bit-usage. Haha :P

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  15
  • Topics Per Day:  0.00
  • Content Count:  161
  • Reputation:   31
  • Joined:  12/06/11
  • Last Seen:  

Refer to my previous post, added a newer script. ^

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  9
  • Topics Per Day:  0.00
  • Content Count:  379
  • Reputation:   304
  • Joined:  11/10/11
  • Last Seen:  

Not really as the space they will placed in is different, unless rAthena didn't really changed it (I just supposed it's like all "normal" IPL's). And as I said before, both ways are correct, but I'd prefer not to use the heap to compute bitmasks, when I can just store values, especially if there can be future updates about the script. Also, are you sure that bitmasks actually set the variable as boolean? I believe that even if it has boolean properties, it's considered as integer, so the memory used won't change, unless you use just one variable and make correspond every bit to a variable value. But the same you can do with integers as well.

I don't say it's wrong to use a method or another, I say it's better to not wasting space by creating multiples vars.

I don't get your sentence about bitmask, the result variable is an INT set by booleans (understand boolean as 0-1 for each bits (0-30) in the INT variable).

@garet999

Not bad, The OnPcLogoutEvent and OnPCDieEvent can be merged.

I don't love the getd ("$@SPVP" + .@PVPUIP$) stuff, it can be improve.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  0
  • Topics Per Day:  0
  • Content Count:  205
  • Reputation:   19
  • Joined:  10/12/12
  • Last Seen:  

I don't say it's wrong to use a method or another, I say it's better to not wasting space by creating multiples vars.

I don't get your sentence about bitmask, the result variable is an INT set by booleans (understand boolean as 0-1 for each bits (0-30) in the INT variable).

I meant that if you want to "save" space, is still better to use decimal system variables more than bits, as you will need to compute more operations for checking bits while it would be way simpler with decimal sys, if you need to save space.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  9
  • Topics Per Day:  0.00
  • Content Count:  379
  • Reputation:   304
  • Joined:  11/10/11
  • Last Seen:  

I meant that if you want to "save" space, is still better to use decimal system variables more than bits, as you will need to compute more operations for checking bits while it would be way simpler with decimal sys, if you need to save space.

You are talking about how to made the script simpler, not how to save space. Or I don't get it and ask you to show me, with an example if you want, how by using more variables, you can save more slots.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  0
  • Topics Per Day:  0
  • Content Count:  205
  • Reputation:   19
  • Joined:  10/12/12
  • Last Seen:  

Bitmasks can only save up to 2 statements, as you correctly compared them to boolean variables. You can have a chain of tons of bits, each of them storing a boolean for an evaluation of 2^n elements. Shifting the bits or using bitmasks, you can get the boolean reference of overy of them. As this process requires a virtual statement, it needs multiple checkings on the bit of the variable you are checking, plus the operation you run to recover the correct bit, while a normal variable declaration just need the time for conversion. Also, if I want a quest to have multiple steps, you can't updrate the variables with bits as both of the 2 status are taken already. So, you can still operate to integer decimal variables, giving a variable 10 possible values instead of 2. The operations will be the same, just it will skip the part of the bit-catching and will reduce again the number of operation the system has to compute (speaking about IPLs, I'm not really a rA expert, it may be there are some particular mechanics that works better with rA more than in other IPLs, that's my limit after all ^^; )

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  9
  • Topics Per Day:  0.00
  • Content Count:  379
  • Reputation:   304
  • Joined:  11/10/11
  • Last Seen:  

Ok I see what you mean.

Yeah it's possible to use this solution, I already use it on the past. But the only advantage is to having the ability to store 10 values (9: 0-9 values and 1: 0-1 value). But in his script, he doesn't need to store values in variables, just need to check if a variable is set, so bit-mask is more natural to use in this case (and faster).

if ( var & 1 << index );
set var, var | 1 << index;

Vs:

if ( var / pow(10,index) % 10 );
set var, var%pow(10,index) + value * pow(10,index) + var/pow(10,index+1)*pow(10,index+1);
// or using setchar, charat.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  15
  • Topics Per Day:  0.00
  • Content Count:  161
  • Reputation:   31
  • Joined:  12/06/11
  • Last Seen:  

Tbh, I'm not too familiar with bit operators, could you give me a small explanation on the above?

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  9
  • Topics Per Day:  0.00
  • Content Count:  379
  • Reputation:   304
  • Joined:  11/10/11
  • Last Seen:  

Well it's difficult for me to explain, it's not my native language.

You have to know that an int variable use 32 bits, here the representation in bit of 315732 : 1001101000101010100.

So with bitmask operator, you can access all 32 bits used in an int variable and it's useful to store booleans values (and other things, but I will not explain here).

So to really simplify you can use '&' to get and '|' to add values.

I use >> << to access values at a specify index.

So basically:

// check for the .@index bit in .@var
if ( .@var & 1 << .@index )
   dothis;

// Set on bit
set .@var, .@var | 1 << .@index;

// Set off bit
set .@var, .@var & ~ (1<<.@index);

Note: index can be a number between 0 and 31.

I would like to show my chess script, but it's difficult to select just some parts of it for this topic.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  15
  • Topics Per Day:  0.00
  • Content Count:  161
  • Reputation:   31
  • Joined:  12/06/11
  • Last Seen:  

Well it's difficult for me to explain, it's not my native language.

You have to know that an int variable use 32 bits, here the representation in bit of 315732 : 1001101000101010100.

So with bitmask operator, you can access all 32 bits used in an int variable and it's useful to store booleans values (and other things, but I will not explain here).

So to really simplify you can use '&' to get and '|' to add values.

I use >> << to access values at a specify index.

So basically:

// check for the .@index bit in .@var
if ( .@var & 1 << .@index )
dothis;

// Set on bit
set .@var, .@var | 1 << .@index;

// Set off bit
set .@var, .@var & ~ (1<<.@index);

Note: index can be a number between 0 and 31.

I would like to show my chess script, but it's difficult to select just some parts of it for this topic.

Thanks, MarkZD gave me some information on this subject as well. I do seem to understand a few parts.

I would like to show my chess script, but it's difficult to select just some parts of it for this topic.

You may add me to an IM or send me a PM if you want so you could show me Sounds interesting :P.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  9
  • Topics Per Day:  0.00
  • Content Count:  379
  • Reputation:   304
  • Joined:  11/10/11
  • Last Seen:  

Well... you are interested, we are talking about bit-mask, so maybe it can inspired some guys around here.

So, as I said, I used bit-mask in my chess script. This script is not released because it's a work in progress I can't test AND because since the CORE is done, I'm not really motivate to do all the rest (npc to register etc.).

When loading I generate some constants (fuck indent):

    // Constantes
   set .WHITE,       1 << 0;
   set .BLACK,       1 << 1;

   set .NONE,        1 << 2;
   set .OVERFLOW,    1 << 3;

   set .PAWN,        1 << 4;
   set .KNIGHT,      1 << 5;
   set .BISHOP,      1 << 6;
   set .ROOK,        1 << 7;
   set .KING,        1 << 8;
   set .QUEEN,       .BISHOP | .ROOK;

And I use this constant each time in the script to optimize the script and make it easy readable.

So basically, setting the chess board:

    // Define the board
   setarray .board[81], .ROOK|.BLACK, .KNIGHT|.BLACK, .BISHOP|.BLACK, .QUEEN|.BLACK, .KING|.BLACK, .BISHOP|.BLACK, .KNIGHT|.BLACK, .ROOK|.BLACK;
   setarray .board[71], .PAWN|.BLACK, .PAWN  |.BLACK, .PAWN  |.BLACK, .PAWN |.BLACK, .PAWN|.BLACK, .PAWN  |.BLACK, .PAWN  |.BLACK, .PAWN|.BLACK;
   setarray .board[21], .PAWN|.WHITE, .PAWN  |.WHITE, .PAWN  |.WHITE, .PAWN |.WHITE, .PAWN|.WHITE, .PAWN  |.WHITE, .PAWN  |.WHITE, .PAWN|.WHITE;
   setarray .board[11], .ROOK|.WHITE, .KNIGHT|.WHITE, .BISHOP|.WHITE, .QUEEN|.WHITE, .KING|.WHITE, .BISHOP|.WHITE, .KNIGHT|.WHITE, .ROOK|.WHITE;

-----------------------------------------------

When player click on a piece, I set a new constant called .ENEMY based on the enemy color.

And all you need to do after, is to check the class, and do what you want.

Example with the pawn movement:

    /// Find movement for PAWN
   if ( .class & .PAWN )
   {
       // Find if the pawn go to the top or to the down
       set .@_to, .class & .WHITE ? 1 : -1 ;

       // Normal movement
       if ( callfunc( "Chess.get_class", .x, .@y + .@_to ) & .NONE ) // no piece here
       {
           callfunc( "Chess.save_cell", .x, .y + .@_to );

           // Move to +2, if not moved yet
           set .@start_point, .class & .WHITE ? 2 : 7;
           if ( .y == .@start_point && callfunc( "Chess.get_class", .x, .y + .@_to * 2 ) & .NONE )
               callfunc( "Chess.save_cell", .x, .y + .@_to * 2 );
       }

       // Attack movement on right
       if ( callfunc( "Chess.get_class", .x + 1, .y + .@_to ) & .ENEMY )
           callfunc( "Chess.save_cell", .x + 1, .y + .@_to );

       // Attack movement on left
       if ( callfunc( "Chess.get_class", .x - 1, .y + .@_to ) & .ENEMY )
           callfunc( "Chess.save_cell", .x - 1, .y + .@_to );

So I extend the system.

Just with bitmask I can know if there is someone in a case (!.NONE, .KING, .ROOK, ...), his color (.WHITE/.BLACK), if it's an enemy (.ENEMY), if I can move here (.MOVABLE) or if I'm out of the board (.OVERFLOW), etc.

I also start a little AI, but not finished it yet.

-----------------------------------------------

It's just an example. There are a lot of better way to use bitmask, but it's awesome when you know how to use it :P

I remember this topic: http://www.eathena.ws/board/index.php?showtopic=273636

When it comes to my brain that this script will be far more optimized using a bitmask check :D

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  0
  • Topics Per Day:  0
  • Content Count:  205
  • Reputation:   19
  • Joined:  10/12/12
  • Last Seen:  

Nice try Key, this is a good solution to try to face in my opinion one of the biggest Athena emulation problem: as you work on storage variables and datas from different players, why didn't developers make Athena (both eA and rA) an Object Oriented language? So easy to work between classes and objects, and to store/load them whenever it is necessary... That's the biggest Athena limit in my opinion. Times ago, I was working myself to try to develop and emphatize the concept of class and struct, oriented to a new system of storing datas, based on OOL of course. Had to drop the project 'cause it was pretty long, hard and my time was almost zero.

Oh and btw, I still believe anyway that the bit process above bitmasks is pretty odd, helps maybe on storing boolean variables or save space, but still slow for the server to compute.

We should release anyway a thread about bitmasks to teach the new generation of scripters what there is in the deep part of the programming.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  9
  • Topics Per Day:  0.00
  • Content Count:  379
  • Reputation:   304
  • Joined:  11/10/11
  • Last Seen:  

The bitmask operation is as fast as + - * operators in rathena so it's faster than using pow() / etc :P

But I agree, the script engine sux, but it will be too difficult to add POO to the engine, it will be faster (and cleaner) to rewrite it from scratch.

The main problem is just that every guys are familiars to the current way to script and changing it on something else will destabilize them.

Funny to see there is nothing related to bitmask on the wiki °°

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  0
  • Topics Per Day:  0
  • Content Count:  205
  • Reputation:   19
  • Joined:  10/12/12
  • Last Seen:  

True thing about POO and destabilization. But I believe that OOrAthena would simplify every kind of problem about storing variables or using bitmasks (not really used this much lol).

And good from rAthena if bit-a-bit operations are this fast to compute, 'cause is not really like that in the most part of IPLs actually used...

Funny to see there is nothing related to bitmask on the wiki °°

That's exactly why I proposed to open up a thread about bitmasks, I'm sure we can develop it pretty well and fast sharing our knowledges (not me and you only, I mean everyone who is good at it).

Link to comment
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.   Paste as plain text instead

  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.

×
×
  • Create New...