• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

In need of a simple Quest System

Status
Not open for further replies.
Level 2
Joined
Mar 27, 2010
Messages
22
Actually, the project I'm working on is the second map I do. The first time, I did a whole mess of triggers to make a quest system, I think there must be s simpler way. Except the F9 quest lobby, is there a way to make a quest system (talking to NPC they give you quest, you do them and come back for a reward)? Example of quest I'd like to do.

You talk to a NPC called John. He says go slay 10 wolves and you'll be rewarded! You kill 10 wolves, and you go talk to him again. He says Thanks there's 200 gold, I appreciate your help! Then talking to him does nothing anymore.

Second one would be a drop quest. Same example (almost) :

You talk to a NPC called John. He says go get me 10 wolves tooth and you'll be rewarded! You get 10 wolves tooth, and you go talk to him again. He says Thanks there's 200 gold, I appreciate your help! Then talking to him does nothing anymore.

Early thanks!

Edit: I just realized that I was in Trigger in Scripts. This probably should be moved in World Editor Help Zone. Sorry 'bout that.
 
Last edited:
Level 28
Joined
Jan 26, 2007
Messages
4,789
Before reading: everything I say will be in GUI.
Using JNGP is not preferred if you only use GUI anyway, and all options above require JNGP (so that wouldn't be the best idea if you're not accustomed with JASS, let alone vJass).


There are different ways you can 'talk' to an NPC.
One is to right-click it, another is to select it (both when near the NPC). You can also just activate it when you're in range of the NPC.

My example will use the 'right-click when in range', simply because you do not have to deselect your hero that way.
The event will be:
  • Events
    • Unit - A unit Is issued an order targeting an object
"targetting an object" can basically be translated to "right-click" when we're talking about neutral units.

We have to be in range of the NPC as well (can't talk to an NPC that is kilometers away).
For this, you have to use points (in GUI at least), so we cannot place it in the "Conditions" section (otherwise we create leaks, and we do not want leaks!).

So this is how you do it:

  • Actions
    • Set tempLoc1 = (Position of (Triggering unit))
    • Set tempLoc2 = (Position of (Target unit of issued order))
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (Distance between tempLoc1 and tempLoc2) Less than or equal to 400.00
      • Then - Actions
        • -------- We're within range --------
      • Else - Actions
    • Custom script: call RemoveLocation(udg_tempLoc1)
    • Custom script: call RemoveLocation(udg_tempLoc1)
You can change the "400.00" if you want.
The custom scripts are to remove leaks. In case you didn't know this yet: please, for your own sake, learn about memory leaks. It's vital for the performance of your map.


Where the comment currently is, we need to display our quest.
Usually, it sends a game message as well, such as:

Quest Discovered: Create a Quest
You must find out how to create your own quest.​

This is a simple game message, I won't show how you do that.
But the quest itself is something most people get lazy on.
There is something called "quest requirements". Most people just skip that and use the quest description to say what people have to do, but not me ;)

A standard way to create quests is:
  • Quest - Create a Optional quest titled Create a Quest with the description You must find..., using icon path {Path}
  • Set quest1 = (Last created quest)
  • Quest - Create a quest requirement for quest1 with the description Follow this guide
  • Set quest1Req1 = (Last created quest requirement)
  • Quest - Create a quest requirement for quest1 with the description Create your own quest
  • Set quest1Req2 = (Last created quest requirement)
  • Set quest1Activated = True
Let's go over it, shall we?
The first thing you do is, obviously, create the quest itself.
Important: set the quest path to something that fits the quest! I've seen so many games where the creator just didn't bother changing the quest path, which is really annoying.
Saving the quest into a variable allows you to mark the quest as completed/failed (also pretty important I assume).

Then you create the quest requirements. These will show up above the quest description.
Again: saving these requirements into variables allows you to mark them as completed/failed.

The last action is something I didn't mention yet: if we already have the quest, we don't want to get it again (unless it failed).
We store "true" in a variable, so whenever this variable is "true", the trigger will not activate (this could be inside the "Conditions"-section of the trigger).


Next thing on the list is getting creeps to drop the required items.

  • Drop Items
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • quest1Activated Equal to True
          • (Unit-type of (Triggering unit)) Equal to Fearsome Wolf
          • (Random percentage) Less than or equal to {Drop chance (percentage)}
        • Then - Actions
          • Set tempLoc1 = (Position of (Triggering unit))
          • Item - Create Wolf Tooth at tempLoc1
          • Custom script: call RemoveLocation(udg_tempLoc1)
        • Else - Actions
I usually use tomes as items. These dissapear when picked up, so they don't take up any inventory space.
This is good when using the standard warcraft 3 inventory, as 6 slots just aren't enough for gear, potions and quest items.

Why didn't I put the conditions of the ITE (If-Then-Else) in the "Conditions"-section of the trigger? So you can use this trigger for all your quests.


When picking up an item (tome), we use the event:
  • Events
    • Unit - A unit Uses an item
    • Unit - A unit Acquires an item
The actions are something like this:
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • (Item-type of (Item being manipulated)) Equal to Wolf Tooth
      • quest1ItemCount Less than quest1ItemsRequired
      • quest1Activated Equal to True
    • Then - Actions
      • Set quest1ItemCount = (quest1ItemCount + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • quest1ItemCount Greater than or equal to quest1ItemsRequired
        • Then - Actions
          • -------- All wolf teeth have been found, complete the quest requirement --------
          • -------- Optional: add a special effect (question mark) above the NPC's head --------
          • Quest - Mark quest1Req1 as Completed
        • Else - Actions
          • -------- Show update-message --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Complete Quest <gen> is on) Equal to False
        • Then - Actions
          • Trigger - Turn on Complete Quest <gen>
        • Else - Actions
      • Set LoopIntQ = 100
    • Else - Actions
The update-message could be:

Quest Updated: Wolf Quest
Wolf Teeth found: 2 / 10

Anyhow, a little recap on the trigger:
Conditions:
1) Item type must be correct (obviously)
2) We may not have more than the maximum amount of quest items (avoids things like "Wolf Teeth found: 11/10").
2) The quest must still be active.

We increase the amount of items we have found and then check whether we've found them all, or should keep on hunting.


Now we need to complete our trigger. We do this the same way we started it: right-clicking the NPC.
The event is the same as the first trigger, but the conditions of the ITE are slightly different:
  • Actions
    • Set tempLoc1 = (Position of (Triggering unit))
    • Set tempLoc2 = (Position of (Target unit of issued order))
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (Distance between tempLoc1 and tempLoc2) Less than or equal to 400.00
        • quest1Activated Equal to True
        • quest1Completed Equal to False
        • quest1ItemCount Greater than or equal to quest1ItemsRequired
      • Then - Actions
        • -------- Give rewards --------
        • Set quest1Completed = True
        • Quest - Mark quest1Req2 as Completed
        • Quest - Mark quest1 as Completed
      • Else - Actions
    • Custom script: call RemoveLocation(udg_tempLoc1)
    • Custom script: call RemoveLocation(udg_tempLoc1)
The quest still has to be active, but may not be completed yet.

I usually put "Return to {NPC}" as the second quest requirement, so that's why we only mark it as completed here.
We have to complete the quest itself as well.

Rewards are quest-specific.



And that's the basics :D

I may add a system of my own if you ask so (I also made a quest system, in GUI though, a long time ago).
 
Level 2
Joined
Mar 27, 2010
Messages
22
For this, you have to use points (in GUI at least), so we cannot place it in the "Conditions" section (otherwise we create leaks, and we do not want leaks!).

So this is how you do it:

  • Actions
    • Set tempLoc1 = (Position of (Triggering unit))
    • Set tempLoc2 = (Position of (Target unit of issued order))
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (Distance between tempLoc1 and tempLoc2) Less than or equal to 400.00
      • Then - Actions
        • -------- We're within range --------
      • Else - Actions
    • Custom script: call RemoveLocation(udg_tempLoc1)
    • Custom script: call RemoveLocation(udg_tempLoc1)
You can change the "400.00" if you want.
The custom scripts are to remove leaks. In case you didn't know this yet: please, for your own sake, learn about memory leaks. It's vital for the performance of your map.

I really, but really don't understand what are custom scripts, or even how you can do one!


A standard way to create quests is:
  • Quest - Create a Optional quest titled Create a Quest with the description You must find..., using icon path {Path}
  • Set quest1 = (Last created quest)
  • Quest - Create a quest requirement for quest1 with the description Follow this guide
  • Set quest1Req1 = (Last created quest requirement)
  • Quest - Create a quest requirement for quest1 with the description Create your own quest
  • Set quest1Req2 = (Last created quest requirement)
  • Set quest1Activated = True

Does this use F9 quest system? If it does, I already took all the spots to make Tips and help. (Pretty necessary)

Next thing on the list is getting creeps to drop the required items.

  • Drop Items
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • quest1Activated Equal to True
          • (Unit-type of (Triggering unit)) Equal to Fearsome Wolf
          • (Random percentage) Less than or equal to {Drop chance (percentage)}
        • Then - Actions
          • Set tempLoc1 = (Position of (Triggering unit))
          • Item - Create Wolf Tooth at tempLoc1
          • Custom script: call RemoveLocation(udg_tempLoc1)
        • Else - Actions

If the item isn't a quest item and a normal item. (I mean, it is a normal item that always drop and can be selled as ivory.) I can change it if it's necessary, tough.

The update-message could be:

Quest Updated: Wolf Quest
Wolf Teeth found: 2 / 10

Anyhow, a little recap on the trigger:
Conditions:
1) Item type must be correct (obviously)
2) We may not have more than the maximum amount of quest items (avoids things like "Wolf Teeth found: 11/10").
2) The quest must still be active.

We increase the amount of items we have found and then check whether we've found them all, or should keep on hunting.

How do you store those informations? I mean the */10 stuff.

Last thing: It is a MP map, so doesn't the last created stuff can have leaks when more than one player do a quest? I always hated the last created stuff because they're so leaky. that's why I don't dare to make special effects (permanent) that couldn't be destroyed after because there is no variable and no other premade option that let me do that at all!
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
I really, but really don't understand what are custom scripts, or even how you can do one!
It's the third action in the "All" category :/
Basically: you write a JASS-script in it (so it's not really GUI anymore, it's JASS).

The problem here is that it is required to make your game run smoothly. As I already said: you have to learn how to remove memory leaks.
Does this use F9 quest system? If it does, I already took all the spots to make Tips and help. (Pretty necessary)
Yes, but wouldn't it be possible to put all hints/tips in "Main Quests", and the actual quests in "Optional Quests"?
You can't have used all spots.

How else would you view the quest log?

If the item isn't a quest item and a normal item. (I mean, it is a normal item that always drop and can be selled as ivory.) I can change it if it's necessary, tough.
No, that's also possible. If you can sell it, then it's not bad I guess.
My problem was that some items are really quest-only items, you can't do anything with them aside from collecting. That's why I use times.

How do you store those informations? I mean the */10 stuff.
* is stored as the variable "quest1ItemCount",
10 is stored as the variable "quest1ItemsRequired".

Last thing: It is a MP map, so doesn't the last created stuff can have leaks when more than one player do a quest? I always hated the last created stuff because they're so leaky. that's why I don't dare to make special effects (permanent) that couldn't be destroyed after because there is no variable and no other premade option that let me do that at all!
One thing: Leaks aren't bugs. Leaks are pieces of memory that leak, and thus reduce the performance of your game (make it run slower).
Bugs are things that go wrong.

You didn't say quests had to be for 1 player only... when you have a request, please be more clear about that ;)
So yeah, it won't work if you want each player to be able to do the quests separately.

There ARE special effects variables by the way... besides: special effects always have to be removed (aaalwaaayyss :D).
So you can remove special effects by simply assigning a variable to it.
 
Level 2
Joined
Mar 27, 2010
Messages
22
My tought

Leaks aren't bugs. Leaks are pieces of memory that leak, and thus reduce the performance of your game (make it run slower).
Bugs are things that go wrong.

You didn't say quests had to be for 1 player only... when you have a request, please be more clear about that ;)
So yeah, it won't work if you want each player to be able to do the quests separately.

There ARE special effects variables by the way... besides: special effects always have to be removed (aaalwaaayyss :D).
So you can remove special effects by simply assigning a variable to it.

Really sorry 'bout that. And about leaks, the point is that I already tried to put in variable for special effects, and there's no way to. Yeah I setted it in a trigger, otherwise it doesn't let me choices. But it COULD be because I'm using the very first editor (no updates on it, so no hashtable). I don't know.. Otherwise, for the quest, the first system I did was bugless BUT it was all about item drop/pick. Example:


  • FirstQuest Start
  • Events:
    • Unit - Unit enters (FirstQuest <gen>)
  • Conditions:
    • (Red Quests 001 <gen>) has an item of type (FirstQuest Start) is equal to TRUE
    • (Red Quests 001 <gen>) has an item of type (FirstQuest Progress) is equal to FALSE
    • (Red Quests 001 <gen>) has an item of type (FirstQuest End) is equal to FALSE
  • Actions:
    • Game - Show the message: Blablabla for 5.00 seconds for (Owner of(Triggering unit))
    • Hero - Create (FirstQuest Progress) and give it to (Red Quests 001 <gen>)
    • Hero - Make (Red Quests 001 <gen>) drop (FirstQuest Start) from slot inventory 1
Now I had to put the conditions of completition, whatever it was, in another trigger, and It gave "FirstQuest End" items to the hero (wich is actually an item such a Wolf Teeth in that case). So if you come back with 10 wolf tooth, you get FirstQuest End. To end all this:

  • FirstQuest End
  • Events:
    • Unit - Unit enters (FirstQuest <gen>)
  • Conditions:
    • (Triggering unit) has an item of type (Whatever item) is equal to TRUE
  • Actions:
    • --------Whatever Reward--------
    • Hero - Create (FirstQuest End) and give it to (Red Quests 001 <gen>)
    • Hero - Make (Red Quests 001 <gen>) drop (FirstQuest Progress) from slot inventory 2
This was how I made it first, roughly. With alot of mistake, probably. Anyway, those FirstQuest stuff are items that a unit called Red Quests 001 will either drop or get. It has first quest start, so you can have first quest progress and when you got the right items in you inventory (hero one), you go speak to the guy and he replace it with first quest end that you get but not on your hero (it gives it to the red quests), so you cant do it anymore. this require place in the map 'ight. The dropped items are deleted by a cleanup system that clean the zone wich was QuestRegion <gen> if I remember. That's quite complicated, it works tough. I could redo it, since I only have 6 player max (I had 12 before :eekani:) and it will take less place.
 
Last edited:
Status
Not open for further replies.
Top