Quests

Original Thread from fulminus here: http://www.l2jserver.com/forum/viewtopic.php?f=46&t=4515 This is a tutorial on how to write simple events with Jython. By "simple events" I mean events of the style of L2Day or Medal. That is: Events that add some global drops from all mobs to all people with the same chance, and then maybe have some NPCs give rewards for these drops. This does NOT include pvp events or races (for suggestions on how to do pvp/race events, please see: http://forum.l2jdp.com/viewtopic.php?t=2821) This tutorial is valid as of August 28, 2006. However, as it's using a class in java, it is subject to breaking due to future changes in the java code. I cannot guarantee that I will keep this up to date in the far future. Now, let's start. There are 2 steps to creating an event: 1) Create the script for the universal drops (and even announcements) 2) Create the script for the rewards. Step 1: a) Create a folder in your gameserver\data\jscript\ for this example, let's say we call this folder Event1 b) in the __init__.py file in gameserver\data\jscript\ add a line to direct your server to load up this new folder. This is a sample of how this file will look like with this change: c) Now save and close this file. d) go in your gameserver\data\jscript\Event1\ folder and create a new file. Name this file __init__.py This is the file where your script for the global drops will go e) You will need to write the code for the event drops and event announcements. I will first give you a sample code and then analyze and explain it step by step so that you may more comfortably know what to change and how to change it for your needs :) Now let's go through it step by step: After some comments and printouts to help you monitor if your event is loading, the first thing I do is import my classes. EventDropList and Announcements are java classes from the l2j core side that handle global event drops and announcements. The DateRange and GregorianCalendar classes are from the actual java (sun microsystems) code and is unlikely to change much. It is needed in order to be able to define the daterange during which your event will be running. Next, I do: You should notice here that the format defining a date is 4 digit year, month-1, day. Be careful about the month. In Java, months go from 0 to 11 instead of 1 to 12. January is 0, April is 3, and so on. After I've defined and initialized my temp1 with the date that I want, I assign the date+time for it to my StartDate variable. Since I hadn't defined a time, it assumes midnight. So my event will start on the 16th of April 2006. Each time the server reboots, if the server's date is before April 16 2006, it won't load the event at all. Repeat in the same manner to define the EndDate... Next, create a "DateRange" using the StartDate and EndDate variables that we just defined. EventDates = DateRange(StartDate, EndDate) So now, if the server's date is after the EndDate, it won't load the event drops. You can leave this event in your server for ever. It won't create any problems with your server and it will only run for the dates defined. If you ever want to re-run the same event, all you will need to do is edit the script to change the dates and reboot your server. You don't need to keep deleting and recreating these events in order to stop them ;) Now that you have the Event Date Range, you need to create a list of items to drop and the chance for these drops. Actually, event drops allows you to create a big list of drops all of which have a certain chance. If you want to have different chances for different items, you can create multiple lists, each with its own chance. In my example, I created 3 lists. One list contains L2Day letters that I wanted to be common, one with the medium, and one with the rare letters...then I assigned chance values for each of these lists. So my drops have 3 different chances now. The variable Count states the min and max amount of drops for the items in the list. In this example, I wanted all items to only drop once from each kill, so I made my count be [1,1]. If you wanted all your items to have min 1 and max 3, you could just set count=[1,3]. It's pretty straight forward. What you must be careful with is count affects ALL drops in the same list. Again, if you want different items to have different min/max counts, you ought to add each drop as a separate list with its own count. Finally, add each list with its chance using This concludes adding the event drops. These drops will be given by ALL mobs. The chance is affected by the level difference between player and mob. A lv 70 char can't just kill gremlins in order to rip the rewards. These event drops do not affect the drop categories. To add an event announcement, I used the code Here, EventDates is the same variable I had defined earlier for the event drops. It holds the daterange during which this announcement will be shown. After the date, you can have a comma-delimited list of text within single quotes. Each element of this list is an announcement that each person will see the moment the log into the server. In my example, I only wanted 1 announcement. If you want to have many lines of announcements for this event, just do something like this: Again, these announcements will only be shown if the server's dates are within the event dates, so you don't need to delete them manually! You can leave this script unchanged in your server for ever and nobody will have any idea it's still there after the end of the event! :D Similarly, you can have announcements shown after the end of the event by creating a new daterange and adding these separately like: In this example, I created a date range that starts from the end of the event and goes till 1 week later. Then I put my list of 3 announcements for the event (event dates) and at the next line I put my announcement for the end of the event. I hope that's not too confusing ;) Finally, the last line in my sample code is just a little print out...if there is an error in the script, this line will fail to be printed at server boot, so looking for this line in your log is a good way to check if your script loaded properly.

Now that we have the global event drops, it's time to add the rewards...this is a lot simpler. It takes no more than a usual jython quest script...Unfortunately, unlike the event drops and event announcements, the rewards section cannot be date-controlled as easily. Can be done? Yes...but you'd have to redefine the event dates and manually check the current date of the server and compare it to the ones you defined...it's not really worth the trouble, imo. Anyhow, here is what you can do: go to gameserver\jscript\custom Create a new directory (let's call it Event1) open the __init__.py in gameserver\jscript\custom and add the necessary lines to load up this Event1 folder (same way as it was explained earlier for the event drops script) open your gameserver\jscript\custom\Event1 folder and create an __init__.py file in it. Edit this file as you need for your rewards. Save the file. Reboot the server.

A sample file would be something like: NOTE: The below code works only up until DP revision 2800! For code that works with more recent revisions, please look further down in this thread! See: http://forum.l2jdp.com/viewtopic.php?p=25575#25575 What I did in this custom script is: If a person talks to the event manager (id 12260), he/she will receive 1 synth cokes for each common letter, 1 mythril alloy for each medium letter, and 1 mold glue for each rare letter. Of course, those are only sample rewards...you can change them as you please. People will be able to access this script via the quest link on that NPC's dialog. You may need to change the dialog a little if you want to give it a better feel for your players. Since this script cannot be auto-disabled by date, and you probably don't want to delete and recreate it in the future when you reuse your event, what I recommend is this: When your event is over and you are ready to disable the rewards, just edit the __init__.py file of the gameserver\data\jscript\custom folder and remove the loading for your Event1 folder from that script. BTW, I personally recommend that you keep the rewards script enabled for at least 1-2 weeks after the end of your event. This gives people a chance to trade with each other the event drops and/or claim the rewards for items they had received but hadn't had a chance to go cash in yet...

A final comment: This implementation does NOT include anything that will auto-delete the event items from people's inventories after the end of the event. This can also be implemented with a little effort, but I <brdo not recommend it. Instead, you can do a simple query to delete these from the items table directly (preferably while the server is down for maintenance and after you've backed it all up). The following query will delete all the quest items from my example from people's inventories, wh, clan wh, and freight: Feel free to ask any questions. I hope this guide was helpful and not too confusing for you.

To enable certain parts of the quest, you must bind the NPC to use them. 1) addFirstTalkId(NPC id) means that once you double-click on the NPC, it will run the onFirsTalk part of the quest. 2) addStartId(NPC id) will run the onTalk part. 3) addTalkId(NPC id) will run the onEvent and onAdvEvent parts (usually ony one of them is used). Each npc requires these bindings. You can also do something like: NPCS = {1,2,3,4} for NPC in NPCS: addStartId(NPC) which will use the addStartId for all NPCS. If any of these functions are present in the quest script, but are not bound to the NPC(s) or called in the script itself, they will not run. more of these function can be found in com.l2jserver.gameserver.model.quest.Quest.java.