Jump to content
  • 0

Killcount


Valenneth

Question


  • Group:  Members
  • Topic Count:  2
  • Topics Per Day:  0.00
  • Content Count:  6
  • Reputation:   0
  • Joined:  08/09/12
  • Last Seen:  

Hi, First of all I am deeply sorry for adding 1 more post to the forum >.<

I'd like to request a Quest NPC that requires players to kill a certain amount of monsters (let's say 1000 Porings), and if possible, the player have to kill the monster while wearing a certain accessory or it won't be counted for the quest.

After that is done, the next step of the quest is that the NPC will give the player 3 random question using input command from a set of 20, before giving the reward.

Start Quest -> Kill 1000 Porings while wearing accessory -> answer 3 random questions in input -> Get reward.

I hope it's not too much of a trouble >.< I'm new to scripting, advanced commands and variables kinda kills me >.<

I also would be really grateful if anyone can give me a link to a guide for advanced scripting, like switch, setarrays, etc.

Link to comment
Share on other sites

8 answers to this question

Recommended Posts


  • Group:  Members
  • Topic Count:  72
  • Topics Per Day:  0.02
  • Content Count:  2997
  • Reputation:   1130
  • Joined:  05/27/12
  • Last Seen:  

Everything you need is in doc\script_commands.txt, though I admit it's hard searching for specific commands when you only have a description in mind.

Hunting quests can either be done through db\quest_db.txt or an NPC script. Since you want the monster kills to only count with an accessory equipped, you have to use a script:

OnNPCKillEvent: // this activates each time a monster is killed
if (quest_variable == value) { // check if player has the quest first (for efficiency)
	if (killedrid == 1002 && isequipped(accessory_id)) { // additional checks
		set kill_count_variable, kill_count_variable+1; // add kill to counter
		if (kill_count_variable == 1000) // notify the player
			dispbottom "You are done the quest.";
	}
}
end;

You'll probably need to add/set other variables to check what part of the quest the player is on. As for the random questions, use a switch() statement:

switch(rand(20)) { // will output a number 0,1,2,3,...19
case 0:
	set .@question$,"This is your first question!";
	set .@answer$,"This is the first answer!";
	break; // break out of the switch()
case 1: // etc.
//...
case 19: // etc.
}
mes .@question$;
input .@str$; // any variable, since these are temporary
if (.@str$ == .@answer$) {
mes "Correct!";
getitem item_id,amount;
close;
}
else {
mes "Incorrect.";
   close;
}

To ask multiple questions, possibly use a for() loop and give the reward when the loop variable is 3.

  • Upvote 1
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  2
  • Topics Per Day:  0.00
  • Content Count:  6
  • Reputation:   0
  • Joined:  08/09/12
  • Last Seen:  

Thank you for your time to reply and help, I really appreciate it. Yeah.., it's hard to find specific command when you only have an idea as the base, adds to it that I'm the type that learns faster from looking at example than reading theory. :\

About the killcount script, if I want to add another set of it, do I just add another sets of killcount variable after the 1st one?

like : (tested it and it worked, just wanna know if there's something wrong with it).

OnNPCKillEvent: // this activates each time a monster is killed
if (Legendary3 == 1) { // check if player has the quest first (for efficiency)
	if (killedrid == 1002 && isequipped(2782)) { // additional checks
		set Recording, Recording+1; // add kill to counter
		if (Recording >= 2000) // notify the player
			dispbottom "=======THE RING GLOWS BRIGHT AFTER ACCUMULATING ENOUGH EXAMPLES=======";
	}
}
if (Legendary3 == 2) { // check if player has the quest first (for efficiency)
	if (killedrid == 1113 && isequipped(2782)) { // additional checks
		set Recording2, Recording2+1; // add kill to counter
		if (Recording2 >= 1000) // notify the player
			dispbottom "=======THE RING SHINES BRIGHT AFTER ACCUMULATING ENOUGH EXAMPLES=======";
	}
}
end;
}

I dunno much about athena capability, so idk wether the count continues or reset if the player doing the quest logged out or dc mid killing.

And does other party member kills also added to the counts of other party member?

As for the random question, it worked also, many thanks. Still trying to figure out how to make it ask more questions before giving prize ^^;;

Sorry for the trouble >.< , I just learned scripting for only like.... a week. I'm loving every moment of it though. (that sense of accomplishment once you make something works)

Edited by Valenneth
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  72
  • Topics Per Day:  0.02
  • Content Count:  2997
  • Reputation:   1130
  • Joined:  05/27/12
  • Last Seen:  

The script looks good. You might want to do something like

set Legendary3,2;
set Recording,0;

...after the player kills the first 2000 monsters, so you'll be able to use the same "Recording" variable and additional kills of the first monster won't still be counted.

Party kills are complicated. You probably don't want to get involved with that yet. xD

The variable is permanent. There are two types of character variables:

@var - temporary (resets on relog)
var - permanent

You can read more about variable types here: http://rathena.org/w...bles.2C_and_Set

To ask more questions, run a for() loop:

for(set .@i,0; .@i<3; set .@i,.@i+1) {	// ask 3 questions
// set .@i,0; -- initialize a variable (technically not needed, but a good habit)
// .@i<3; -- run until .@i becomes >= 3
// set .@i,.@i+1 -- increase .@i by 1 upon reaching the end of the for() bracket
switch(rand(20)) {...}
mes .@question$;
input .@str$;
if (.@str$ == .@answer$) {
	if (.@i < 2) {	// only run this when there's actually a question left, xD
		mes "Good! Now for the next question...";
		next;
	}
}
else {...}
}
mes "You've answered all the questions!";

More details here: http://rathena.org/wiki/Loops#For_Loop

  • Upvote 1
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  2
  • Topics Per Day:  0.00
  • Content Count:  6
  • Reputation:   0
  • Joined:  08/09/12
  • Last Seen:  

Hi again ^^. First of all, thank you so much for putting a description for each strings and vars, it taught me more than reading the list of commands in the doc. XD

Yeah I put the first code somewhere after the player return and talk to the npc. So every poring they kill after the 2000th poring will make the dispbottom message shows up (to remind them). But I guess I will add Recording,0 somewhere so I can use the same var again for the 2nd killcount.

set Legendary3,2;
set Recording,0;

Just wondering...., does the first one makes the same char unable to repeat the quest again ? or the whole account ?. Since the reward will be good, I don't want players to spam it, so I want it once per account only. I do put:

if ( (Legendary3 == 0) && (countitem(6048) > 0) ) goto L_NoQuest; //Char did not start quest yet.
if (Legendary3 == 1) goto L_Legendary3_1; //Char accepted quest 1.
if (Legendary3 == 2) goto L_Legendary3_2; //Char accepted quest 2.
goto L_Finish; //Char finished all quests from npc.

for(set .@i,0; .@i<3; set .@i,.@i+1) {	// ask 3 questions
// set .@i,0; -- initialize a variable (technically not needed, but a good habit)
// .@i<3; -- run until .@i becomes >= 3
// set .@i,.@i+1 -- increase .@i by 1 upon reaching the end of the for() bracket
switch(rand(20)) {...}
mes .@question$;
input .@str$;
if (.@str$ == .@answer$) {
	if (.@i < 2) {	// only run this when there's actually a question left, xD
		mes "Good! Now for the next question...";
		next;
	}
}
else {...}
}
mes "You've answered all the questions!";

Thanks man, This works nicely. I had the gist of what to type in the for(), just didnt know where should i put it at, and didnt know about

if (.@i < 2) {	// only run this when there's actually a question left, xD

Is it possible in current athena to make NPC roam around the map then stop when someone is accessing them ?

I tried :

OnTimer3000: // <----- I put this at the start of script
npcwalkto 70+rand(50),135+rand(50);
setnpctimer 0;

OnInit: // <---- I put this set at the end of the script
 initnpctimer;
	end;

But the npc walks after being clicked ^^;;

And does sleep command can be used to make some sort of delay before player gets their reward??, like maybe wait 1 day before they can proceed with the quest. ??

Edited by Valenneth
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  72
  • Topics Per Day:  0.02
  • Content Count:  2997
  • Reputation:   1130
  • Joined:  05/27/12
  • Last Seen:  

You can use an account variable - they're prefixed with #, e.g. #CASHPOINTS.

Random walking:

    npcstop; // stop when clicked
   stopnpctimer; // stop timer when clicked
   // dialogue (the rest of the script)
   initnpctimer; // resume timer before closing (do this before all "close" commands)
   close;
OnInit:
   initnpctimer;
   end;
OnTimer3000:
   getmapxy(.@map$,.@x,.@y,1); // get coordinates
   npcwalkto .@x+rand(-10,10),.@y+rand(-10,10); // walk +/- 10 randomly
   stopnpctimer; // restart timer
   initnpctimer;
   end;

Use gettimetick(2) for large delay intervals. Also, you'll have to use a permanent character/account variable to store the data, for example:

// player has finished the quest
mes "Come visit again after 24 hours for your reward.";
set quest_delay, gettimetick(2)+86400; // 86400 seconds = 1 day
close;

if (quest_delay > gettimetick(2))
   mes "Please wait a little longer.";
else {
   mes "Thanks for waiting!";
   mes "Here's your reward.";
   getitem item,amount;
}
close;

  • Upvote 1
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  2
  • Topics Per Day:  0.00
  • Content Count:  6
  • Reputation:   0
  • Joined:  08/09/12
  • Last Seen:  

Sorry for the late reply, got pretty busy irl @_@. So to make the npc wait before proceeding, roam around the map and make the quest only doable once per account, it should be something like this ?

npcstop;
stopnpctimer;

if (#TESTINGTIME == 0) goto Z_NoQuest;
if (#TESTINGTIME == 1) goto Z_TESTINGTIME_1;
goto Z_Finish;

Z_TESTINGTIME_1:
if ( (quest_delay > gettimetick(2)) && (countitem(520) >= 1) ) goto L_TESTINGTIME_1_b;
mes "^FF0000[Testing Delay]^000000";
mes "It's not ready yet man, come back later";
initnpctimer;
close;
Z_TESTINGTIME_1_b:
mes "^FF0000[Testing Delay]^000000";
mes "Reward !!!!";
set #TESTINGTIME,#TESTINGTIME+1;
getitem "Red Potion",100;
initnpctimer;
close;

Z_NoQuest:
mes "^FF0000[Testing Delay]^000000";
mes "ETCETCETCBLAHBLAH";
menu "Take Quest",-;
mes "^FF0000[Testing Delay]^000000";
mes "BLABLABLABLABLABLABLABLA";
set quest_delay, gettimetick(2)+86400;
set #TESTINGTIME,1;
initnpctimer;
close;

Z_Finish:
mes "^FF0000[Testing Delay]^000000";
mes "Quest Finished for this account.";
initnpctimer;
close;

OnInit:
initnpctimer;
end;
OnTimer3000:
getmapxy(.@map$,.@x,.@y,1); // get coordinates
npcwalkto .@x+rand(-100,100),.@y+rand(-100,100); // walk +/- 10 randomly
stopnpctimer; // restart timer
initnpctimer;
end;
}

Edited by Valenneth
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  72
  • Topics Per Day:  0.02
  • Content Count:  2997
  • Reputation:   1130
  • Joined:  05/27/12
  • Last Seen:  

if ( (quest_delay > gettimetick(2)) && (countitem(520) >= 1) ) goto L_TESTINGTIME_1_b;

  1. quest_delay < gettimetick(2)
  2. The label doesn't exist.

You don't have to use two variables. If you store time (gettimetick) in #TESTINGTIME and run

if (#TESTINGTIME) // any number except 0 (i.e. quest started)

...that'll suffice for all checks.

Try not to use as many labels/goto when you can just use brackets - if(condition){script}

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  2
  • Topics Per Day:  0.00
  • Content Count:  6
  • Reputation:   0
  • Joined:  08/09/12
  • Last Seen:  

@_@ You mean use character/account variable as the quest_delay ??

yeah i need to change my habbit to using brackets ^^;;

Edited by Valenneth
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...