Jump to content
Angelix

Create a Quest

Recommended Posts

Custom Quest Part I

Making the players kill other players within the quest.

Spoiler

In this part of the guide, I'll be showing you how to add a little trick to make quest that ask for killing players. It's a bit more complicated since you'll have to edit an already existing function, add a new function and a new line within CharacterInfo. You'll be following the same structure from Simple Quest Part II, I'll just show what to modify and add.

 

Lets start by adding a new line within CharacterInfo:


<CHARACTERINFO_ID>	<CHARACTER_NAME>	Long Haired Guy	1	1	0	0	100	2000	255	464	640	816	0	0	0	0,0	0	0,0,0	1	1	100	182	-1	-1	0	0	0	1,2,3,4,7,8	1.051	1.369	2.599	40	1,5	0,0	399	398	0	0	0,0,0	1	1	0	0	25,28,29,30,31,34,35,38	100	0	0	0	0	0	0	0	1	1	1000	0	0	1	0	1	40	0	18	0	4	5	0	3	2	1	1	0	1	1	1442	0	1500	480	0	5	5	5	5	5	5	20	0	0	0	0	20	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	1.0,1.0,1.0
  • CHARACTERINFO_ID: This should be a new number not used.
  • CHARACTER_NAME: This should be the name you want to appear within the quest as it will appear as "Hunt <CHARACTER_NAME> X/Y", for this, just set it at "Players".

 

Then open up your functions.lua and add this somewhere inside:


function CustomQuest(ATKER, DEFER)
	if HasMission(ATKER, <MISSION_ID>) == 1 then
		AddNextFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
		local Count = GetNumFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
		BickerNotice(ATKER, "Killed Players ["..Count.."/<AMOUNT_NEEDED>]!")
	end
end

Then within the same file, search for this function:


after_player_kill_player

Inside that function, place this:


CustomQuest(ATKER, DEFER)

Like I said, following the same structure as Simple Quest Part II, that will be everything you need to do in order to make the quest.

 

Custom Quest Part II

Making the players kill other players only within a certain map for the quest.

Spoiler

Following the same structure from Custom Quest Part I.

 

Go to the function you have added:


CustomQuest(ATKER, DEFER)

Replace this:


function CustomQuest(ATKER, DEFER)
	if HasMission(ATKER, <MISSION_ID>) == 1 then
		AddNextFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
		local Count = GetNumFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
		BickerNotice(ATKER, "Killed Players ["..Count.."/<AMOUNT_NEEDED>]!")
	end
end

For this:


function CustomQuest(ATKER, DEFER)
	if HasMission(ATKER, <MISSION_ID>) == 1 then
		if GetChaMapName(ATKER) == "<MAP_NAME>" then
			AddNextFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
			local Count = GetNumFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
			BickerNotice(ATKER, "Killed Players in <TRUE_MAP_NAME> ["..Count.."/<AMOUNT_NEEDED>]!")
		end
	end
end
  • MAP_NAME: This being the name of the map where you want kills to get registered only.
  • TRUE_MAP_NAME: This being the real name on the map you placed, example being "Forsaken City" for "abandonedcity".

 

Custom Quest Part III

Making the players kill other players that are only a certain class for the quest.

Spoiler

Following the same structure from Custom Quest Part I.

 

Lets start by adding a new line within CharacterInfo:


<CHARACTERINFO_ID>	<CLASS_NAME>	Long Haired Guy	1	1	0	0	100	2000	255	464	640	816	0	0	0	0,0	0	0,0,0	1	1	100	182	-1	-1	0	0	0	1,2,3,4,7,8	1.051	1.369	2.599	40	1,5	0,0	399	398	0	0	0,0,0	1	1	0	0	25,28,29,30,31,34,35,38	100	0	0	0	0	0	0	0	1	1	1000	0	0	1	0	1	40	0	18	0	4	5	0	3	2	1	1	0	1	1	1442	0	1500	480	0	5	5	5	5	5	5	20	0	0	0	0	20	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	1.0,1.0,1.0
  • CHARACTERINFO_ID: This should be a new number not used.
  • CLASS_NAME: The name of the class that will appear in the quest.

 

After that, we modify the following function:


CustomQuest(ATKER, DEFER)

Change:


function CustomQuest(ATKER, DEFER)
	if HasMission(ATKER, <MISSION_ID>) == 1 then
		AddNextFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
		local Count = GetNumFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
		BickerNotice(ATKER, "Killed Players ["..Count.."/<AMOUNT_NEEDED>]!")
	end
end

To:


function CustomQuest(ATKER, DEFER)
	if HasMission(ATKER, <MISSION_ID>) == 1 then
		if GetChaAttr(DEFER, ATTR_JOB) == <CLASS_ID> then
			AddNextFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
			local Count = GetNumFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
			BickerNotice(ATKER, "Killed <CLASS_NAME> Players ["..Count.."/<AMOUNT_NEEDED>]!")
		end
	end
end
  • CLASS_ID: This is the number belonging to the class you chose to create the CharacterInfo ID.
    • If you chose "Crusader", then this would be 9, and so on.
  • CLASS_NAME: The true name of the class you chose to put in this quest.

 

Custom Quest Part IV

Making the players kill other players that are only a certain type of character for the quest.

Spoiler

Following the same structure from Custom Quest Part I.

 

Lets start by adding a new line within CharacterInfo:


<CHARACTERINFO_ID>	<CHARACTER_NAME>	Long Haired Guy	1	1	0	0	100	2000	255	464	640	816	0	0	0	0,0	0	0,0,0	1	1	100	182	-1	-1	0	0	0	1,2,3,4,7,8	1.051	1.369	2.599	40	1,5	0,0	399	398	0	0	0,0,0	1	1	0	0	25,28,29,30,31,34,35,38	100	0	0	0	0	0	0	0	1	1	1000	0	0	1	0	1	40	0	18	0	4	5	0	3	2	1	1	0	1	1	1442	0	1500	480	0	5	5	5	5	5	5	20	0	0	0	0	20	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	1.0,1.0,1.0
  • CHARACTERINFO_ID: This should be a new number not used.
  • CHARACTER_NAME: The name of the type of character that will appear in the quest.

 

After that, we modify the following function:


CustomQuest(ATKER, DEFER)

Change:


function CustomQuest(ATKER, DEFER)
	if HasMission(ATKER, <MISSION_ID>) == 1 then
		AddNextFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
		local Count = GetNumFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
		BickerNotice(ATKER, "Killed Players ["..Count.."/<AMOUNT_NEEDED>]!")
	end
end

To:


function CustomQuest(ATKER, DEFER)
	if HasMission(ATKER, <MISSION_ID>) == 1 then
		if GetChaTypeID(DEFER) == <CHARACTER_ID> then
			AddNextFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
			local Count = GetNumFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
			BickerNotice(ATKER, "Killed <CHARACTER_NAME> Players ["..Count.."/<AMOUNT_NEEDED>]!")
		end
	end
end
  • CHARACTER_ID: This is the number belonging to the character type you chose to create the CharacterInfo ID.
    • If you chose "Lance", then this would be 1.
    • If you chose "Carsise", then this would be 2.
    • If you chose "Phyllis", then this would be 3.
    • If you chose "Ami", then this would be 4.

 

Custom Quest Part V
Making the players kill other players that are inside a certain map and are a certain type of character for the quest.

Spoiler

This is a mixed type from Custom Quest Part II and Custom Quest Part IV.

 

You only need to modify the following function:


CustomQuest(ATKER, DEFER)

Change:


function CustomQuest(ATKER, DEFER)
	if HasMission(ATKER, <MISSION_ID>) == 1 then
		if GetChaTypeID(DEFER) == <CHARACTER_ID> then
			AddNextFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
			local Count = GetNumFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
			BickerNotice(ATKER, "Killed Players ["..Count.."/<AMOUNT_NEEDED>]!")
		end
	end
end

 

To:


function CustomQuest(ATKER, DEFER)
	if HasMission(ATKER, <MISSION_ID>) == 1 then
		if GetChaMapName(DEFER) == "<MAP_NAME>" then
			if GetChaTypeID(DEFER) == <CHARACTER_ID> then
				AddNextFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
				local Count = GetNumFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
				BickerNotice(ATKER, "Killed <CHARACTER_NAME> Players in <TRUE_MAP_NAME> ["..Count.."/<AMOUNT_NEEDED>]!")
			end
		end
	end
end
      

 

  • The variables are already explained in other parts of the guide.

Custom Quest Part VI
Making the players kill other players that are inside a certain map and are a certain type of class for the quest.

Spoiler

This is a mixed type from Custom Quest Part II and Custom Quest Part III.

 

You only need to modify the following function:


CustomQuest(ATKER, DEFER)

Change:


function CustomQuest(ATKER, DEFER)
	if HasMission(ATKER, <MISSION_ID>) == 1 then
		AddNextFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
		local Count = GetNumFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
		BickerNotice(ATKER, "Killed Players ["..Count.."/<AMOUNT_NEEDED>]!")
	end
end

 

To:


function CustomQuest(ATKER, DEFER)
	if HasMission(ATKER, <MISSION_ID>) == 1 then
		if GetChaMapName(DEFER) == "<MAP_NAME>" then
			if GetChaAttr(DEFER, ATTR_JOB) == <CLASS_ID> then
				AddNextFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
				local Count = GetNumFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
				BickerNotice(ATKER, "Killed <CLASS_NAME> Players <TRUE_MAP_NAME> ["..Count.."/<AMOUNT_NEEDED>]!")
			end
		end
	end
end

 

  • The variables are already explained in other parts of the guide.

Custom Quest Part VII

Making the players kill other players that are only a certain type of character and class for the quest.

Spoiler

This is a mixed type from Custom Quest Part III and Custom Quest Part IV.

 

You only need to modify the following function:


CustomQuest(ATKER, DEFER)

Change:


function CustomQuest(ATKER, DEFER)
	if HasMission(ATKER, <MISSION_ID>) == 1 then
		AddNextFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
		local Count = GetNumFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
		BickerNotice(ATKER, "Killed Players ["..Count.."/<AMOUNT_NEEDED>]!")
	end
end

 

To:


function CustomQuest(ATKER, DEFER)
	if HasMission(ATKER, <MISSION_ID>) == 1 then
		if GetChaTypeID(DEFER) == <CHARACTER_ID> then
			if GetChaAttr(DEFER, ATTR_JOB) == <CLASS_ID> then
				AddNextFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
				local Count = GetNumFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
				BickerNotice(ATKER, "Killed <CHARACTER_NAME> <CLASS_NAME> Players ["..Count.."/<AMOUNT_NEEDED>]!")
			end
		end
	end
end

 

  • The variables are already explained in other parts of the guide.

Custom Quest Part VIII
Making the players kill other players that are inside a certain map, are a certain class and a certain type of character.

Spoiler

This is a mixed type from Custom Quest Part II, Custom Quest Part III and Custom Quest Part IV.

 

You only need to modify the following function:


CustomQuest(ATKER, DEFER)

Change:


function CustomQuest(ATKER, DEFER)
	if HasMission(ATKER, <MISSION_ID>) == 1 then
		AddNextFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
		local Count = GetNumFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
		BickerNotice(ATKER, "Killed Players ["..Count.."/<AMOUNT_NEEDED>]!")
	end
end

 

To:


function CustomQuest(ATKER, DEFER)
	if HasMission(ATKER, <MISSION_ID>) == 1 then
		if GetChaMapName(DEFER) == "<MAP_NAME>" then
			if GetChaTypeID(DEFER) == <CHARACTER_ID> then
				if GetChaAttr(DEFER, ATTR_JOB) == <CLASS_ID> then
					AddNextFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
					local Count = GetNumFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
					BickerNotice(ATKER, "Killed <CHARACTER_NAME> <CLASS_NAME> Players in <TRUE_MAP_NAME> ["..Count.."/<AMOUNT_NEEDED>]!")
				end
			end
		end
	end
end

 

  • The variables are already explained in other parts of the guide.

Custom Quest Part IX

Making the quest only able to repeat once per day or per week.

Spoiler

This is somewhat the same as Simple Quest Part III.

 

You need to add the following functions to MissionSdk.lua:


function getYearBeginDayOfWeek(tm)
	local yearBegin = os.time{year=os.date("*t",tm).year,month=1,day=1}
	local yearBeginDayOfWeek = tonumber(os.date("%w",yearBegin))
	if (yearBeginDayOfWeek == 0) then
		yearBeginDayOfWeek = 7
	end
	return yearBeginDayOfWeek
end
function getDayAdd(tm)
	local yearBeginDayOfWeek = getYearBeginDayOfWeek(tm)
	local dayAdd = 0
	if (yearBeginDayOfWeek < 5) then
		dayAdd = (yearBeginDayOfWeek - 2)
	else 
		dayAdd = (yearBeginDayOfWeek - 9)
	end  
	return dayAdd
end
function getWeekNumberOfYear()
	local tm = os.time{year=tonumber(os.date("%Y")),month=tonumber(os.date("%m")),day=tonumber(os.date("%d"))}
	local dayOfYear = os.date("%j",tm)
	local dayAdd = getDayAdd(tm)
	local dayOfYearCorrected = dayOfYear + dayAdd
	if (dayOfYearCorrected < 0) then
		dayAdd = getDayAdd(os.time{year=os.date("*t",tm).year-1,month=1,day=1})
		dayOfYear = dayOfYear + os.date("%j", (os.time{year=os.date("*t",tm).year-1,month=12,day=31}))
		dayOfYearCorrected = dayOfYear + dayAdd
	end  
	local weekNum = math.floor((dayOfYearCorrected) / 7) + 1
	if ((dayOfYearCorrected > 0) and weekNum == 53) then
		if (getYearBeginDayOfWeek(os.time{year=os.date("*t",tm).year+1,month=1,day=1}) < 5 ) then
			weekNum = 1
		end  
	end  
	return weekNum
end
function QuestFunc(Player, Mission, Type, Func)
	local Name = GetChaDefaultName(Player)
	local Day = (tonumber(os.date("%Y")) * 10000) + (tonumber(os.date("%m")) * 100) + (tonumber(os.date("%d")))
	local Week = (tonumber(os.date("%Y")) * 100) + getWeekNumberOfYear()
	if QuestLog == nil then
		QuestLog = {}
	end
	if QuestLog[Name] == nil then
		QuestLog[Name] = {}
	end
	if QuestLog[Name][Mission] == nil then
		QuestLog[Name][Mission] = {}
	end
	if Type == "Daily" then
		if QuestLog[Name][Mission][Day] == nil then
			QuestLog[Name][Mission][Day] = false
		end
		if Func == "Check" then
			if QuestLog[Name][Mission][Day] == false then
				return LUA_TRUE
			elseif QuestLog[Name][Mission][Day] == true then
				return LUA_FALSE
			end
		elseif Func == "Completed" then
			QuestLog[Name][Mission][Day] = true
			return LUA_TRUE
		end
	elseif Type == "Weekly" then
		if QuestLog[Name][Mission][Week] == nil then
			QuestLog[Name][Mission][Week] = false
		end
		if Func == "Check" then
			if QuestLog[Name][Mission][Week] == false then
				return LUA_TRUE
			elseif QuestLog[Name][Mission][Week] == true then
				return LUA_FALSE
			end
		elseif Func == "Completed" then
			QuestLog[Name][Mission][Week] = true
			return LUA_TRUE
		end
	end
end

Within the same file, look for:


			elseif conditions[i].func == NoRecord then
					..
				end

Then right above (or below) it, add this:


			elseif conditions[i].func == QuestFunc then
				local ret = QuestFunc(character, conditions[i].p1, conditions[i].p2, conditions[i].p3)
				if ret ~= LUA_TRUE then
					return LUA_FALSE
				end

Then, within the same file look for this:


		elseif actions[i].func == SetRecord then
				...
			end

Then right above (or below) it, add this:


		elseif actions[i].func == QuestFunc then
			local ret = QuestFunc(character, actions[i].p1, actions[i].p2, actions[i].p3)
			if ret ~= LUA_TRUE then
				return LUA_FALSE
			end

 

Then, as mentioned above, doing the same thing as Simple Quest Part III, but with a little change:

 

Add this MisBeginCondition:


MisBeginCondition(QuestFunc, <MISSION_ID>, <MISSION_TYPE>, "Check")

Then add this MisResultAction:


MisResultAction(QuestFunc, <MISSION_ID>, <MISSION_TYPE>, "Completed")
  • MISSION_ID: This being the ID of your mission.
  • MISSION_TYPE: This can only be two choices (they have to be typed as followed, even with quotation marks):
    • "Daily": Quest only repeatable once a day.
    • "Weekly": Quest only repeatable once a week.

 

DISCLAIMER: These "daily" or "weekly" quest will not persists through server restarts, if you want them to persists, modify function in order to work with text logs.

 

  • Like 4
  • Thanks 1

Share this post


Link to post
Share on other sites

Extra Quest Functions Part I

Adding rewards to quests.

Quote

Taking a look at the format from "Simple Quest Part I", you can add some functions to give players items, gold or do other actions.

 

After this line:


MisResultAction(ClearMission, <MISSION_ID>)

You can either go two ways about adding items or gold as rewards. This method will not show anything, just give the rewards to the player when completing the quest. You can add this lines below the line mentioned above.


	MisResultAction(AddExp, <AMOUNT_EXP_START>, <AMOUNT_EXP_END>)
	MisResultAction(AddMoney, <AMOUNT_GOLD_START>, <AMOUNT_GOLD_END>)
  • It will give a random amount of experience between "<AMOUNT_EXP_START>" and "<AMOUNT_EXP_END>", it will give a set amount of experience if both numbers are the same.
  • It will give a random amount of gold between "<AMOUNT_GOLD_START>" and "<AMOUNT_GOLD_END>", it will give a set amount of experience if both numbers are the same.

You can also go with a more visual way of adding rewards by adding these below "MisResultAction(ClearMission, <MISSION_ID>)":


	MisResultBagNeed(<SPACES_NEEDED>)
	MisPrize(MIS_PRIZE_ITEM, <ITEM_ID>, <ITEM_QUANTITY>, <ITEM_QUALITY>)
	MisPrize(MIS_PRIZE_MONEY, <GOLD_AMOUNT>, 1)
	MisPrizeSelAll()

The needed things are pretty much self explanatory and by using this method, it will show at all times the rewards that will be obtained in the quest log.

Extra Quest Functions Part II

Adding the quest to an NPC.

Quote

For the player to be able to obtain the quest, they need to talk to an NPC, it's very easy to add.
You take this first line you created:


DefineMission(<QUEST_ID>, <QUEST_NAME>, <MISSION_ID>)

With that, you add this at the end of the NPC you want players to obtain the quest.
 


	AddNpcMission(<QUEST_ID>)

 

Extra Quest Functions Part III

Adding the quest to the client so it shows the proper name on quest log.

Quote

With this line:


DefineMission(<QUEST_ID>, <QUEST_NAME>, <MISSION_ID>)

You open up your client files and open this specific file: Client\scripts\lua\mission\missioninfo.lua and then add this in there:


AddMisData(<MISSION_ID>, <QUEST_NAME>, <QUEST_TYPE>)
  • <MISSION_ID>: Same as the first line of the quest created.
  • <QUEST_NAME>: Same as the quest name in first line.
  • <QUEST_TYPE>: You can put "1" being a normal quest or "2" being a story quest.

 

Edited by Angelix
Added guide to add quest to NPC.
  • Thanks 1

Share this post


Link to post
Share on other sites

Updated, enjoy.

 

Added a part to show how to chain quests, by making a condition to have another quest already completed in order to start the new quest.

 

Maybe in the next days I'll put up the part on how to make a quest that requires you to talk to other NPCs, just like the quest originally used in ToP that asks you to talk to other NPCs to become a voyager.

Edited by Angelix
  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

@Angelix I would suggest explanaining how to put 'randomized' items needed/mobs to kill/ rewards (from a list), such as in Class Quests (like a Swordsman's Life / Hunter's Life etc).

 

It is a mechanic that if i will ever get back to making novel servers i will use (and i know how, it should be public that's all).

 

Edit : forgot to tag :/

Edited by Maximilian

Share this post


Link to post
Share on other sites
7 minutes ago, Maximilian said:

@Angelix I would suggest explanaining how to put 'randomized' items needed/mobs to kill/ rewards (from a list), such as in Class Quests (like a Swordsman's Life / Hunter's Life etc).

 

It is a mechanic that if i will ever get back to making novel servers i will use (and i know how, it should be public that's all).

 

Edit : forgot to tag :/

I don't know yet how exactly they work, give me some minutes since I'm currently updating this guide in another tab, hahah. Adding a new type of quest. :)

Share this post


Link to post
Share on other sites

@Angelix Oh the class quests i listed are fairly self explanatory,  it's not hard to grasp at all.

I am on mobile so pardon me for my likely inaccuracy but as far as i remember, it's a series of strings with the level requiremet,  the kind of mob and the likelyhood you have to get it compared to other (and how many).

 

There is one different sub-function for each kind of 'subject' , being defined as either mobs/items/rewards.

Share this post


Link to post
Share on other sites

Guide has been updated with a custom feature, I will later amplify more requirements on that function, enjoy.

 

1 minute ago, Maximilian said:

@Angelix Oh the class quests i listed are fairly self explanatory,  it's not hard to grasp at all.

I am on mobile so pardon me for my likely inaccuracy but as far as i remember, it's a series of strings with the level requiremet,  the kind of mob and the likelyhood you have to get it compared to other (and how many).

 

There is one different sub-function for each kind of 'subject' , being defined as either mobs/items/rewards.

I'll take a look when I can and then write here how to make them as part of the guide. :P

  • Like 1

Share this post


Link to post
Share on other sites

This is great guide very useful!

 

7 hours ago, Angelix said:

I'll take a look when I can and then write here how to make them as part of the guide. :P

This maybe helpful, I had asked about random quests in the past I think in serverdv forum and this is how I think it work: (though I didn't finally do it, so some things I still don't know what is)

 

Random mob to kill:

AddRandKillInfo(    level    ,    monsterid,    randvalue,    randscope,    exp    ,    money    )
AddRandKillInfo(    10    ,    206    ,    3    ,    2    ,    4028    ,    4000    )

10 = Char level
206=  id of mob to hunt (mini bee in this one)
3 = minimum number of mobs to hunt
2 = variation: minimun number + 2, quest can ask kill 3, 4, or 5 (3+2) mobs
4028: Quest gives 201g money reward at round 1 (roughly 4028/20) and each round increases by 40 (2 first digits)
4000: Quest give 200exp first round (4000/20) and increase 40 each round

 

Random item to collect:

AddRandGetItem( level, itemid, randvalue, randscope, exp, money )
AddRandGetItem(	10	,	4485	,	3	,	2	,	4028	,	4000	)

Same as above:
10 = Char level
4485=  id of item to collect (Bee Wing)
3 = min number of items
2 = variation
4028 and 4000: money and exp as above

 

Random give item to other NPC:

AddRandSendInfo( level, npcid, exp, money )
AddRandSendInfo(	80	,	41	,	727500	,	86569	)

AddRandSendItem( level, item )
AddRandSendItem(	80	,	1850	)

80 = level
41 = npc ID
727500 and 86569 money and exp

1850 is parcel

 

Price (randomised)

SetRandPrizeItem( level )
SetRandPrizeItem(	10	)

AddRandPrizeItem( level, item1, itemdata1, item2, itemdata2, item3, itemdata3, item4, itemdata4 )				
AddRandPrizeItem(	10	,	290	,	810	)

level 10, item reward 290 (husk armor) and itemdata 810 I am not sure what means

 

Cycling quests (quest complete every 10 rounds)

SetRandPrizeOdds( loopnum, odds, completenum )
SetRandPrizeOdds( 1, 100, 10 )

completenum (10) is the number of quests to complete a cycle. I don't know how the other two are cacluleted

  • Like 4

Share this post


Link to post
Share on other sites
17 hours ago, KONG said:

ladies and gentlemen, this is how a guide should be. 
Neat, Clean, and Organized. Nice job @Angelix

Thanks for the sticky as well! I've been busy with some final things at school this week, so probably on the weekend I'll update it a bit including the randomizer example/request given by @Maximilian and @SoundX. I'll also try to add to make daily and weekly quests, along with more derivations from the "kill players" conditions, such as map, class and character type specific conditions. 

  • Like 2

Share this post


Link to post
Share on other sites

The guide has been updated with more custom features, enjoy!

 

The following has been added:

  • Ask players to kill within a certain map.
  • Ask players to kill a certain class (ex: crusader, champion, etc.).
  • Ask players to kill a certain type of character (ex: lance, carsise, phyllis or ami).
  • Ask players to kill a certain class within a map (ex: abandonedcity, darkswamp, etc.).
  • Ask players to kill a type of character within a map (ex: a crusader in abandonedcity).
  • Ask players to kill a type of class and character type (ex: a lance  crusader).
  • Ask players to kill a type of class and character within a map (ex: a lance crusader within abandonedcity).
  • Make daily or weekly quest.
    • Please notice that this has been untested and may not work, although I think daily quest should work, not sure about weekly.

 

Note: Even after been told where to look and explained a bit, I haven't got around messing with the randomized quest, that is what I'm going to do next, I think.

  • Like 1

Share this post


Link to post
Share on other sites

The guide has been updated, enjoy!

 

Updates:

  • Fixed some typos in the guide.
  • Add a triggered BIckerNotice to the custom quest when killing players, you may adjust that now to your needs.

 

Issues:

  • The BickerNotice persists even after completing the amount of kills needed.

 

Small Update Edit:

Apply this and it should fix the above mentioned issue of the spamming of BickerNotice, although it was tested a bit, an issue may occur when having two of the same flags; example being your first flag being 10 and the amount needed being 11 resulting in 20, while your second flag being 20 with the amount needed being 1, resulting in 20 as well. Well, that's also an issue with normal monster killing quests though, not my issue. :P

 

Other than that, I don't think any more issues will arise, if they do, please let me know by making a comment and I'll try to see if the fix is within my knowledge.

 

I was editing the whole thread on custom quests with the new modifications and had a little error when trying to save, I lost all the progress and I'm too lazy to go again and edit it, so just use the following piece of code to fix the issue.

 

Please use this as the base and modify to your needs.

function CustomQuest(ATKER, DEFER)
	if HasMission(ATKER, <MISSION_ID>) == 1 then
		if IsFlag(ATKER, <MISSION_ID>, <FLAG_PLUS_AMOUNT_MINUS_ONE>) == 0 then
			AddNextFlag(ATKER, <MISSION_ID>, <MISSION_FLAG>, <AMOUNT_NEEDED>)
		end
	end
end

 

Small Note (to myself):

Save the thread after every single edit made, never know when there's going to be a quick blackout and won't be able to save the thread later.

 

 

Enjoy!

Edited by Angelix
  • Like 1

Share this post


Link to post
Share on other sites
13 hours ago, TheSamurai said:

Thanks @Angelix BickerNotice is working properly now.

 

 

Glad to hear that, if any issue shows up regarding that, please let me know so I can see if there's fix for it.

  • Like 1

Share this post


Link to post
Share on other sites

Got this error with Daily Quest

http://screenshot.sh/m1QsTif8T73Kv

 

can you help me?'

its my function NpcState:

function NpcState( character, npcid, id )
   PRINT( "NpcState:character, npcid, NpcMissionList", character, npcid, id )
	if NpcInfoList[id] == nil or NpcInfoList[id].missionlist == nil then
		PRINT( "unable to obtain NPC script notice!ID = ",  id )
		LG( "npc_error", "unable to obtain NPC script notice!ID = ",  id )
		return LUA_FALSE
	end

   return MissionState( character, npcid, NpcInfoList[id].missionlist )
end

 

Share this post


Link to post
Share on other sites

Great guide, but how are Quests "assigned" to NPCs? I mean, how does one make the Quest accepted at X NPC and then completed at Y NPC (or completed at X NPC, doesn't matter).

 

Rookie question, but I haven't seen it explained anywhere in the Guide. :rolleyes2:

 

Edit: Figured out the first part, but still clueless on how to make the quest finished at a different NPC.

Edited by Leba

Share this post


Link to post
Share on other sites

@LebaTry looking inside your server files and search for quests. There are some story quests which use what you want, get quest at X character and then complete at Y character. Such an example is this:

 

	DefineMission(206, "A Small	Task", 203)
	MisBeginTalk("<t>Actually,	I wanted	To ask you	To	Investigate certain strange happenings	In Shepherd Plains.<n><t>However, before	That,	I still have	To	Test you.<n><t>Go	To <pArgent City Harbor> at(2277, 2831)and look for <bGeneral - William>. He will give you	The next	Task.")
	MisBeginCondition(NoRecord, 203)
	MisBeginCondition(NoMission, 203)
	MisBeginCondition(HasRecord, 200)
	MisBeginAction(AddMission, 203)
	MisCancelAction(ClearMission, 203)
	MisNeed(MIS_NEED_DESP, "Look for <bGeneral - William>	In <pArgent City Harbor> at(2277, 2831)")
	MisHelpTalk("<t>Is	There anymore questions?	If not, please go and see <bGeneral William>, he has a	Task for you.")
	MisResultCondition(AlwaysFailure)

	DefineMission(207, "A Small	Task", 203, COMPLETE_SHOW)
	MisBeginCondition(AlwaysFailure)
	MisResultTalk("<t>Ah, Salvier	Is a weird fella, sending us an unknown adventurer.	Doesn't he	Trust	The Navy?<n><t>Come back when you're	Ready.	I have a job for you")
	MisResultCondition(NoRecord, 203)
	MisResultCondition(HasMission, 203)
	MisResultAction(ClearMission, 203)
	MisResultAction(SetRecord, 203)
	MisResultAction(AddExpAndType,2,875,875)


Initially my guide is more centered towards the new functions of getting player kills. I did however add how to create the common quests since almost no one can create a functional quests so simple, but that was not my main focus. I never added the random quests, travel quests (like the one you asked for) and a few other that may be seen on story quests.

Share this post


Link to post
Share on other sites
2 hours ago, Angelix said:

 

@LebaTry looking inside your server files and search for quests. There are some story quests which use what you want, get quest at X character and then complete at Y character. Such an example is this:

 

Oh, thanks so much. I was overthinking it and forgot I could just take a look at such a quest in the files.

2 hours ago, Angelix said:

Initially my guide is more centered towards the new functions of getting player kills. I did however add how to create the common quests since almost no one can create a functional quests so simple, but that was not my main focus. I never added the random quests, travel quests (like the one you asked for) and a few other that may be seen on story quests.

No worries, I understand what the point of your guide was and nothing I said was meant as criticism, your guide is titled "Create a Quest", so not including some finesses such as every type of quest, especially if unrelated to your guide, makes perfect sense.

 

P.S. I was simply wondering how to make the quest finished at a different NPC, not about travel quests per se, but I guess the concept should pretty much the same with added condition(s), so thanks again!

Edited by Leba

Share this post


Link to post
Share on other sites
31 minutes ago, Leba said:

P.S. I was simply wondering how to make the quest finished at a different NPC, not about travel quests per se, but I guess the concept should pretty much the same with added condition(s), so thanks again!

 

The concept is the same. You have to make two script of quests, one that starts at NPC X and another to finish it at NPC Y, no added conditions or anything else. Take a look at the example I provided, it shows two "DefineMission" statements, meaning two quests, one should be in NPC X to start and another at NPC Y to finish.

  • Like 1

Share this post


Link to post
Share on other sites
9 minutes ago, MCHund said:

How do I add the function of having the NPC give an item at the end of the quest?

MisResultAction(GiveItem, ItemID, Amount, Quality) worked for me.

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
Reply to this topic...

×   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.


×
×
  • Create New...