PDA

View Full Version : coming soon


Tark
02-05-2004, 11:13 AM
Scorpious2k and I worked this out. It's a brand new extension to the quest system that is going to expand the what can be done in quests and in interracting with mobs. It works in both perl and old quest format. It is in use now on the Scorpious2k server and will be in CVS soon, if it isn't already.

I am going to break this into several parts to try to explain global variables.

What this does is give mobs the ability to "remember" events. Sort of like making a sticky note for future events or sending instant messages to other mobs. It allows the quest writer to save variables for use in future quests. It gives a lot of flexibility. You will also have to make some changes to the database with the quest_globals.sql.

Here is how to use it..

It uses 3 commands: setglogal, targlobal and delglobal.

==========
Setglobal:
==========
[old quest format]
setglobal([varname],[value],[options],[duration]);

[perl format]
quest::setglobal([varname],[value],[options],[duration]); (perl format)

The setglobal command allows you to create or modify an existing global variable for the mob you are using the command on.

==========
targlobal:
==========
[old quest format]
targlobal([varname],[value],[duration],[npcid],[charid],[zoneid]);

[perl format]
quest::targlobal([varname],[value],[duration],[npcid],[charid],[zoneid]);

This is a way to "stick" a global variable to a mob. A quick and easy way to give information to a mob or communicate.

==========
delglobal:
==========
[old quest format]
delglobal([varname]);

[perl format]
quest::delglobal([varname]);

This command is used to delete global variables when they are no longer needed. You can only delete global variables that belong to the mob the variable is for.

===================
Command Parameters:
===================

[varname] the name of the variable you want to save. Do not include the variable prefix as part of the name. When the quest for the npc who recieves this variable begins, a variable with the name that you here preceeded by a "$" will be available. For example, if [varname] is "genius" then a variable named $genius will be available to the quest script of the npc with whatever you specified in it.

[value] this is what the variable will contain when the quest script begins.

[options] value determines the availability of global variables to NPCs when a quest begins

+--------+---------+---------+----------+
| value | npcid | player | zone |
+--------+---------+---------+----------+
| 0 | this | this | this |
| 1 | all | this | this |
| 2 | this | all | this |
| 3 | all | all | this |
| 4 | this | this | all |
| 5 | all | this | all |
| 6 | this | all | all |
| 7 | all | all | all |
+--------+---------+---------+----------+

this way you can decide what mobs can "see" the variable.


[duration] the amount of time this variable will be available. After this time, the variable goes away! It is a number preceeded by a letter, where the letter can be:


+--------+----------+------------------------------------------------+
| Letter | Time is | examples |
+--------+----------+------------------------------------------------+
| S |seconds| "S15" = 15 seconds |
| M |minutes| "M30" = 30 minutes |
| H | hours | "H12" = 12 hours |
| D | days l "D90" = 90 days |
| Y | years | "Y5" = 5 years |
| T | time | "T012345" = 1 hr, 23 min, 45 sec |
| C | calendar| "C010215" = 1 yr, 2 months, 15 days |
+--------+----------+------------------------------------------------+


[npcid] the id for the target npc from the npc_types table

[charid] the character id from the character_ table for the targetted player

[zoneid] the NUMBER of the zone where the targetted npc is located

In my next message I will give an example.

Shadow-Wolf
02-05-2004, 12:31 PM
sounds very interesting can't wait until you realease more...

smogo
02-05-2004, 12:40 PM
if i get it well, to have a npc remember the last time a char was met, forgetting after 7 days :

quest::targlobal("last_met",getDate(),"D7",$mobid,$user,$zoneln);


then maybee (this is just an idea, not tested):

sub EVENT_SAY{
/hail/i && (defined $last_met) && quest::say("Hail, i remember you. Didn't we chat on $last_met");

/hail/i && (!defined $last_met) && do {
quest::say("Hello $name. I think this is the first time we meet, right ?");
quest::targlobal("last_met",getDate(),"D7",$mobid,$user,$zoneln);
}


then , if this correct, is it possible to add the options to local variables too (allowing to set last_mem in the above example for all zones at a time) ?

Well, asking for an addition on a not yet released new feature ... Please forgive me in advance, it would be SOOOO nice.

Anyway, what you are bringin' in is great !

Tark
02-05-2004, 01:57 PM
This is a 2 part quest. It really is more of a fun thing, but you'll see. It's in perl, because that is what we use on the Scorpious2k server.

It involves two begger type NPCs. One in oasis and one in qeynos2. We call it the "begger-prince quest". Here is the quest file for the one in oasis:

sub EVENT_SAY
{
if($text=~/Hail/i)
{
quest::say("Do you have some loose change for a gentleman who has had some bad luck?");
}
elsif($text=~/yes/i)
{
quest::say("Would you give me some of it please?");
}
else
{
quest::say("Go away and leave me alone in my misery.");
}
}
sub EVENT_ITEM
{
$gotcash=0;
if ($copper>0 || $silver>0 || $gold>0 or $platinum>0)
{
$gotcash=1;
}
$numitems=0;
if ($item1 !="")
{
$numitems=$numitems+1;
}
if ($item2 !="")
{
$numitems=$numitems+1;
}
if ($item3 !="")
{
$numitems=$numitems+1;
}
if ($item4 !="")
{
$numitems=$numitems+1;
}
if ($numitems>0)
{
if ($numitems==1)
{
if ($gotcash=1)
{
quest::say("Thank you so much for the money and the $item1.");
}
else
{
quest::say("Thank you so much for the $item1.");
}
}
else
{
if ($gotcash=1)
{
quest::say("Thank you so much for the money and the other $numitems nice things you gave me.");
}
else
{
quest::say("Thank you so much for the $numitems things you gave me.");
}
}
}
quest::say("May the gods bless you as you journey");
}

sub EVENT_DEATH
{
quest::shout("My brother will avenge my death! There will be no mercy for the murderer $name!!");
quest::targlobal("beggerprince","2","Y1",260,$charid,2);
}

Basically, the begger begs. How's that for unexpected? OK, so what happens? He begs, if you give him money or an items he thanks you. BUT, if you kill him, it sticks a variable on another NPC - the one in qeynos2. That could be an expensive mistake as you'll see in the second half of this.

The targlobal function is used to stick the $beggerprince variable with a value of "2" onto the npc in qeynos2. In a way, this npc has sent an instant message to the one in qeynos2, letting him know this player has killed him! There is a new variable called $charid. This is the id number of this character in the database. You have to use this and not $userid in the targlobal command. They are not the same thing.

Here is the quest file for the NPC in qeynos2...

sub EVENT_SAY
{
if ($beggerprince=="2")
{
quest::say("I know you!! You are the one who killed my brother in Oasis!!");
quest::shout("Die murderer!!");
quest::attack($name);
}
elsif($beggerprince=="1")
{
quest::say("Hello again, my kind friend!");
}
elsif($beggerprince=="3")
{
quest::say("Please don't hurt me again!!");
}
elsif($text=~/Hail/i)
{
quest::say("Do you have some loose change for a gentleman who has had some bad luck?");
}
elsif($text=~/yes/i)
{
quest::say("Would you share some of it please?");
}
else
{
quest::say("Go away and leave me alone in my misery.");
}
}
sub EVENT_ITEM
{
if ($beggerprince=="2")
{
quest::say("I know you!! You are the one who killed my brother in Oasis!!");
quest::say("Do you think you can BUY my forgiveness??");
quest::shout("Die murderer!!");
quest::attack($name);
}
elsif($beggerprince=="3")
{
quest::say("Thank you. Perhaps you are not a bad person after all.");
quest::faction(101,100);
}
elsif($beggerprince=="1")
{
quest::say("Ahhhhhhh! More kindness from my friend!");
quest::say("and this time I will accept your gift and pass it on to the poor and needy");
quest::say("just as I know you would want it.");
quest::faction(101,100);
}
else
{
$gotcash=0;
if ($copper>0 || $silver>0 || $gold>0 or $platinum>0)
{
$gotcash=1;
}
$numitems=0;
if ($item1 !="")
{
$numitems=$numitems+1;
}
if ($item2 !="")
{
$numitems=$numitems+1;
}
if ($item3 !="")
{
$numitems=$numitems+1;
}
if ($item4 !="")
{
$numitems=$numitems+1;
}
quest::say("I must confess... I am not a begger. I am a prince.");
quest::say("I have been seeking a generous person. Until now I have failed.");
quest::say("You have restored my faith in the kindness of others.");
quest::say("Let me show you my gratitude.");
if ($gotcash==1)
{
quest::givecash(0,0,$copper,($platinum*100)+($gold *10)+$silver);
quest::say("Here is 100 times the money you gave me");
}
if ($numitems>0)
{
quest::summonitem($item1,1);
if ($numitems==1)
{
quest::say("Here is your $item1 back.");
quest::exp(1000);
}
else
{
quest::summonitem($item2,1);
if ($item3 != "")
{
quest::summonitem($item3,1);
}
if ($item4 != "")
{
quest::summonitem($item4,1);
}
quest::say("And here are your items back.");
quest::exp(1000*$numitems);
}
}
}
quest::say("thank you so much for showing me that goodness is not gone");
quest::setglobal("beggerprince","1","0","Y1");
quest::faction(101,500);
}

sub EVENT_DEATH
{
if ($beggerprince=="2")
{
quest::shout("My brother! I have failed you!!!!!!");
}
else
{
quest::shout("Why have you done this to me??????????????");
quest::setglobal("beggerprince","3","0","Y1");
}
}


As you can see, we have a global variable in use called $beggerprince. $beggerprince is a type "0" global variable. That means that it is only for this NPC and player. Each player has a different $beggerprince variable, so the value in it is specific for that player. We use the setglobal command here because it is for the npc who is setting it.

IF you killed the NPC in oasis, $beggerprince=="2" and he will attack you if you speak to him or try to give him an item. If you kill him in that battle he will shout "My brother! I have failed you!!!!!!".

IF you didn't kill the npc in oasis yet, he will beg. Its a good idea to be generous. As you can see, he will explain he is in fact a prince and not a begger. He returns 100X the money you gave him. He returns the items you gave him and gives you 1000 X the number of items worth of expirience. $beggerprince is set to "1". This is some of the fun.

So, thinks the newbie, I get 100X my money back... I'm going to cash in on this!

Bzzzzzzz! Wrong Mr Newbie. He remembers you. Next time you give him something, he thanks you and KEEPS IT. :-)

There are some other little things that I am sure you can see here. But that pretty much shows an idea of what you can do.

Tark
02-05-2004, 02:07 PM
if i get it well, to have a npc remember the last time a char was met, forgetting after 7 days :

quest::targlobal("last_met",getDate(),"D7",$mobid,$user,$zoneln);


then maybee (this is just an idea, not tested):

sub EVENT_SAY{
/hail/i && (defined $last_met) && quest::say("Hail, i remember you. Didn't we chat on $last_met");

/hail/i && (!defined $last_met) && do {
quest::say("Hello $name. I think this is the first time we meet, right ?");
quest::targlobal("last_met",getDate(),"D7",$mobid,$user,$zoneln);
}


then , if this correct, is it possible to add the options to local variables too (allowing to set last_mem in the above example for all zones at a time) ?

Well, asking for an addition on a not yet released new feature ... Please forgive me in advance, it would be SOOOO nice.

Anyway, what you are bringin' in is great !
Yep it already does that if ($varname ="") then it is not there.

Lurker_005
02-05-2004, 07:18 PM
Very cool! Keep up the good work you guys.

mollymillions
02-05-2004, 08:27 PM
Winners are grinners 8]

Daeath
02-19-2004, 01:12 PM
I hope I don't seem like the ulitmate noob by asking this, but this update avail. in CVS - this only applies if you're using the dev version and can compile it if you have VS 6, correct? I'm only using the precompiled binary version of 5.3DR2 since I'm not one with the VS force...

Monrezz
02-19-2004, 01:30 PM
Its in CVS - see Tertiary's post about compiling with Dev-C++

smogo
03-01-2004, 10:07 PM
There is a misfit around the delglobal and time out global deletion (0.5.3dr+). I would be too affirmative but at first glance :

The database can be updated, but, well, the variable remains set in the package (read : npc quest variable scope) unless it is reset by a new value.

You can change target, zone out and back, ... does not matter.
The only way to get it removed is to have it set to another value. Otherwise, once it's set, it's set until zone reboots. Maybe forcing mob despawn/respawn would work, not sure so far.


I though of a few things to get rid of this, but there are issues :
- in delglobal, you know that you want to delete a value, so you can set it (or rather unset it) in all packages (read : npcs) where it might have been set. The 'might have been' part is not easy, so better unset it everywhere.

- in timeout, we must use 2 queries, one for fetching what is obsolete, the other to delete it (with a few additioanal requirements i won't discuss yet). Then clean up packages as previously detailled for delglobal.


I'm not too much at ease with embperl's code to suggest a software fix, so when using a global so far, don't rely on default value.
- a global must be set to "<none>", "__absent__" or whatever you want set it rather than delete the record.
- you can't count on timeout to unset a variable. Explicitly unset it to a new value after triggering a timer.
- alternativly, you can explicitly unset it at the end of your event handler. But there might be issues on this too.


It'd be nice if someone can post an opinion or a fix :wink: .

P.S. the overall targlobal / setglobal behavior is fully satisfacting imho atm, so hope we wont have to alter it.

samandhi
03-01-2004, 10:47 PM
if i get it well, to have a npc remember the last time a char was met, forgetting after 7 daysI really like this idea. It can make some REALLY good quests better.

Let's say I have added a quest that has the character find a simple flower (that is harder to find that one might think). The reward is faction, and a very nice exp hit... Well, one would think that this quest is NOT reusable because it would be too easy to get major exp from this quest.. BUT, if there were a forget_timer for this npc then you could do this quest again in say 5 or 6 days... Or maybe even use a different quest for the same npc, but only be able to do SO many quests of this NPC per so often...

Sorry I'm not too clear about my thoughts, but it is 5:30 am here and have NOT been to bed yet haha... But, I think you get the picture... This whole Idea of an AI-ish nature ipens up a whole new realm of possiblilites for questing...

Take AC2 for instance. I recently joined the free 10 day trial thing, and got to lvl 23 with my char (out of 45) doing mainly quests, and solo to boot.. First, let me say that the quests that I encountered up to my current level are OUTSTANDINGLY fun whether you are with a group or not.

Secondly, This KIND of questing (that would be possible, or at least similar with this new system in place) would allow more solo-ability on a legit server (which is a very good thing since server capacity is at a premium on most servers). I may have grouped once in the entire trek to lvl 23 (which is NOT to say I am antisocial, but just felt like trying to play solo since people claimed that you CAN play solo). It takes some of the "Nothing but hack-n-slash" part out of EQ (which, sad to say is the major part of EQ these days, besides item hoarding).... And puts the word adventuring back into EQ, where it once was.... It would also allow for more diverse types of classes to reimerge, such as the wizard, and mage, who have a very hard time surviving in this day and age, where everything is based on how hard your sword hits and so on.. You get the idea...

I dont know, let me submit this post, and get some rest.. I will come back tomorrow and see if I myself agree or can understand what I have written here, as I am too damn tired to even proof-read this post (heaven forbit haha)...

smogo
03-01-2004, 11:23 PM
BUT, if there were a forget_timer for this npc then you could do this quest again in say 5 or 6 days...
Yes, that's just what the built in "expiry date" of targlobal and setglobal were meant for, among many other nifty quest/AI improvements, such as :

NPC says : are you a [young Paladin of Brell] ?
you say : i am a young Paladin of Brell.
NPC says : then go and get me this or that

becoming :
NPC says : are you a [young Paladin of Brell] ?
you say : yes.
NPC says : then go and get me this or that


I'm afraid the mistfit i mentionned in the previous post puts them back for a while.
/cry

samandhi
03-02-2004, 12:01 AM
Yeah, but I am excited about the outcome when the great minds come up with a solution...:)

samandhi
03-02-2004, 01:50 AM
Quote:
NPC says : are you a [young Paladin of Brell] ?
you say : i am a young Paladin of Brell.
NPC says : then go and get me this or that


becoming :

Quote:
NPC says : are you a [young Paladin of Brell] ?
you say : yes.
NPC says : then go and get me this or that Cant this already be done that way? for instace.
sub EVENT_SAY {
if($text=~/Hail/i) {
quest::say("Greetings! You must be a stranger or [new to the Hall]. If you are a stranger. be warned that these halls are intended for the Ebon Mask only. If you are found to be a member of another house. you just may feel the sting of a blade in your back.");;
}
if($text=~/i am new to the hall/i) {
quest::say("Then I am glad to make your acquaintance. Have you ever been to Freeport? If not. how would you like to go? It is a test of your cunning we wish. Are you prepared to risk your young life? Are you [ready to venture to Freeport]?");;
}

If you change the line that reads:
if($text=~/i am new to the hall/i) {

To:
if($text=~/yes/i) { Will that not do what you are saying in that particular example you gave?

Mayhap I am concentrating on the wrong thing here, but I would think that with that particular instance, you would not want anything other than what you have... If you made it a boolean, where false = 0, and true is anything else, then you could type ANYTHING in there to activate the next part of the quest. Therefore it would HAVE to be a static string...

Of course you could always add $text strings so that the user can type it a few different ways (read have a few different responses the NPC would accept). Obviously we know that the =~ tells us that we can type "yes", or "Yes", or any variation thereof, as long as the 3 letters "y", "e", and "s" are represented. Your thoughts? Opinions? Likes? dislikes? Favorite color?

P.S. Just threw in that last one to see if you were ACTUALLY paying attention what with that long winded book of mine.. :)

[edit] a global must be set to "<none>", "__absent__" or whatever you want set it rather than delete the record.

And:
The database can be updated, but, well, the variable remains set in the package (read : npc quest variable scope) unless it is reset by a new value.
Silly question, but since we CAN update simple things like loot drops on mobs, then would it not stand to reason that we could simply write a script to reset the value to say 0 ( or whatever the default value is)? I may be missing your point here, so If I am wrong explain a little better what you mean..

smogo
03-02-2004, 02:23 AM
If you change the line that reads:
Code:
if($text=~/i am new to the hall/i) {


To:
Code:
if($text=~/yes/i) {
Will that not do what you are saying in that particular example you gave?
it would, of course. But what i mean is 'yes' would be understood by the npc ONLY after Are you a [young Paladin of Brell] ? , and not in any other context.

To put it in other ways : you never get any answer in a quest to something like 'Yes.'. It wouldn't make sense. The NPC just could not find out what you say yes to. The best answer you could get is '`Yes` what ?'. Thus, in every quest, you have to re-type more or less what the NPC said.

What i was thinking of is keeping track of the context (i.e. the current subject being discussed) so that :
'yes' means 'I am a young paladin of Brell' in that context,
but 'yes' would mean 'I'm thirsty' after the NPC had said 'Are you thirsty ?',
and have the NPC answer '`Yes` what ?' when you answer 'yes' after 'where do you come from ?'

It's not the best way to implement such 'conversations', but yet could give the feel of the NPC understanding what you say, instead of of just matching words. Using a global 'conversation_subject' per NPC per player can give a cheap and funny improvement to quests.

i would'nt start a long discussion in this thread, but i'm planning to post on this subject whenever i'm done with the plugins stuff.

Doodman
03-02-2004, 05:13 AM
It's not the best way to implement such 'conversations', but yet could give the feel of the NPC understanding what you say, instead of of just matching words. Using a global 'conversation_subject' per NPC per player can give a cheap and funny improvement to quests.
I actually think quests should be done that way. It does work to make more natural conversations. Imagine if you talked that way to a buddy of yours:

Jim: Did you see the superbowl?
Joe: Yes I saw the superbowl.
Jim: Did you see that touchdown?
Joe: Yes I saw that touchdown.
Jim: Did you see the extra special half time performance with Janet Jackson and Justin Timberlake?
Joe: Yes I saw the extra special half time performance with Janet Jackson and Justin Timberlake/

No one talks like that.

smogo
03-02-2004, 08:47 AM
@samandhi : sry maybe i went bit fast over the second half of your post :oops: .

i agree to say that there are other ways to do it, but still we need timeout, and th targlobal was giving such convenience at low cost. Just write one set/unset after 1mn proc, one with targlobal, the other using timers, they'll be very different :?.
RED

@Doodman
Nope. :wink:

samandhi
03-02-2004, 10:58 AM
Cool, I understand now what you are meaning.. And this WOULD be a nice thing to have...

Cisyouc
07-22-2004, 06:17 AM
When I try and use this in my quests the npc does not revert to default as if there was an error, but whenever I try and trigger the setglobal() or targlobal() it doesnt work, and people in #support have said my quest is correct, so any thoughts?

What happens is if I have,
#281099.pl
sub EVENT_SAY
{
if($npcvari1 == 0 && $text=~/hail/i)
{
quest::say("Hello! Would you be interested in helping me?");
}
if($npcvari1 == 1 && $text=~/helping/i)
{
quest::say("Thanks!");
quest::targlobal("npcvari1","1","Y5",281099,$charid,26);
quest::me("You have recieved a character flag!");
}
}

When this is run, and you /say helping, the only thing that shows is "Thanks!" and on rehail I get the same "0" message, even after #reloadquest, logging, and zoning.

Any thoughts?

KhaN
07-22-2004, 06:52 AM
people in #support have said my quest is correct
I would like to know what they smoke ?!~

Try something like this, your syntax is wrong.
*#281099.pl
sub EVENT_SAY
{
if ($text=~/hail/i)
{
if($npcvari1 == 0)
{
quest::say("Hello! Would you be interested in helping me?");
$npcvari1="0"; }
}
if($text=~/helping/i)
{
if($npcvari1 == 1 &&
{
quest::targlobal("npcvari1","1","Y5",281099,$charid,26);
quest::say("Thanks!");
quest::me("You have recieved a character flag!");
$npcvari1="0";
}
}
}
You check action done to NPC, then if there is a variable and its value, then you give the action to do.

One important things is to ALWAYS add "quest::targlobal" as the first actions, or you can have bugs.
Also be sure to always perl cache by using command "$npcvari1="0"; ".
*
Hope that will help and GL in dev quests.

Cisyouc
07-22-2004, 07:41 AM
people in #support have said my quest is correct
I would like to know what they smoke ?!~

Try something like this, your syntax is wrong.
*#281099.pl
sub EVENT_SAY
{
if ($text=~/hail/i)
{
if($npcvari1 == 0)
{
quest::say("Hello! Would you be interested in helping me?");
$npcvari1="0"; }
}
if($text=~/helping/i)
{
if($npcvari1 == 1 &&
{
quest::targlobal("npcvari1","1","Y5",281099,$charid,26);
quest::say("Thanks!");
quest::me("You have recieved a character flag!");
$npcvari1="0";
}
}
}
You check action done to NPC, then if there is a variable and its value, then you give the action to do.

One important things is to ALWAYS add "quest::targlobal" as the first actions, or you can have bugs.
Also be sure to always perl cache by using command "$npcvari1="0"; ".
*
Hope that will help and GL in dev quests.

No i dont think you understood the quest, after you complete the quest the NPC should just respond with "Thanks for helping!".

and will

$npcvari1="0";

reset the global back to 0? Becuase thats not what I want.

Thanks in advance.

Cisyouc
07-22-2004, 07:43 AM
Ah, I forgot something. The code above was the syntax I used which they said would work, but they also said to try this. (using $solusek this time for the variable)
sub EVENT_SAY
{
if($text=~/hail/i)
{
if($solusek == "")
{
quest::say("Hello, would you like to [help] me?");
$solusek="";
}
elsif($solusek=="1")
{
quest::say("Thanks for helping me!");
$solusek="";
}
}
if($text=~/help/i)
{
quest::targlobal("solusek","1","Y5",281099,$charid,26);
quest::me("You have recieved a character flag!");
}
}

But THIS doesnt work either.

animepimp
07-22-2004, 04:31 PM
sub EVENT_SAY
{
if($text=~/hail/i)
{
if($solusek == "")
{
quest::say("Hello, would you like to [help] me?");
$solusek="";
}
elsif($solusek=="1")
{
quest::say("Thanks for helping me!");
$solusek="";
}
}
if($text=~/help/i)
{
quest::targlobal("solusek","1","Y5",281099,$charid,26);
quest::me("You have recieved a character flag!");
}
}

But THIS doesnt work either.

If $solusek doesn't exist I don't think ($solusek == "") will ever be true. You should reverse the two and have only an else for the default case. You always want one to happen no matter what so they should not all have conditions. Like this:

sub EVENT_SAY
{
if($text=~/hail/i)
{
if($solusek=="1")
{
quest::say("Thanks for helping me!");
$solusek="";
}
else
{
quest::say("Hello, would you like to [help] me?");
$solusek="";
}
}
if($text=~/help/i)
{
quest::targlobal("solusek","1","Y5",281099,$charid,26);
quest::me("You have recieved a character flag!");
}
}

That way one or the other always happens when they say hail.

Charmy
07-23-2004, 12:08 AM
sub EVENT_SAY
{
if($text=~/hail/i)
{
if($solusek == "")
{
quest::say("Hello, would you like to [help] me?");
$solusek="";
}
elsif($solusek=="1")
{
quest::say("Thanks for helping me!");
$solusek="";
}
}
if($text=~/help/i)
{
quest::targlobal("solusek","1","Y5",281099,$charid,26);
quest::me("You have recieved a character flag!");
}
}

Kk lets start with a few things.

The quest::targlobal command is used to set entries into the sql database, which are then turned into global variables for use in the form $var1, $var2 etc.. however they are not perl global variables.

What this means is, they can't be set as script variables, $var1 = 123 will not work to affect the sql table.

with that lets try to re write the code yes?


sub EVENT_SAY
{
if($text=~/hail/i)
{
if($solusek == "")
{
quest::say("Hello, would you like to [help] me?");
}
elsif($solusek=="1")
{
quest::say("Thanks for helping me!");
}
}
if($text=~/help/i)
{
quest::targlobal("solusek","1","Y5",281099,$charid,26);
quest::me("You have recieved a character flag!");
}
}


Now a few things to look at here, you are trying to set a global variable for a flag, i assume this means you will use this flag with mob number 281099, and i also assume that the script this is put on is infact mob 281099.

now the script above dosen't do what you orignally intended, so lets add the stuff that needs to be added so it will do what you were trying to accomplish.


sub EVENT_SAY
{
if($text=~/hail/i)
{
if($solusek == "")
{
quest::say("Hello, would you like to [help] me?");
}
elsif($solusek=="1")
{
quest::targlobal("solusek","","Y1",281099,$charid,26);
quest::say("Thanks for helping me!");
}
}
if($text=~/help/i)
{
quest::targlobal("solusek","1","Y5",281099,$charid,26);
quest::me("You have recieved a character flag!");
}
}


The Result of this quest wil be.

You say: "Hail Mob 281099."
Mob says: "Hello, would you like to [help] me?"
You say: "I will help you"
You have Recieved a Character Flag!
You say: "Hail Mob 281099"
Mob says: "Thanks for helping me!"
You say: "Hail mob 281099"
Mob says: "Would you like to [help] me?"
You say: "I will help you"
You have Recieved a Character Flag!
You say: "Hail Mob 281099"
Mob says: "Thanks for helping me!"

just a big long loop!!

If you were to start off by just saying
"I will help you"
then hail he would say
"Thanks for helping me!"
if you said
"i will help you"
again, he would say
"Thanks for helping me!"
on the next hail, now you could aviod this by putting in a variable check right after the $text =~/help/i line


sub EVENT_SAY
{
if($text=~/hail/i)
{
if($solusek == "")
{
quest::say("Hello, would you like to [help] me?");
}
elsif($solusek=="1")
{
quest::targlobal("solusek","","Y1",281099,$charid,26);
quest::say("Thanks for helping me!");
}
}
if($text=~/help/i)
{
if($solusek != "1")
{
quest::targlobal("solusek","1","Y5",281099,$charid,26);
quest::me("You have recieved a character flag!");
}
else # $solusek does = 1
{
quest::say("Yes, i know you will help me!");
}
}
}


Now a little thing i have found about quests, i have run into a problem multiple times that for some odd reason doesn't set the varialbe to the exact $charid. i.e.

"Hail, Mob!"
"Hello Bob, are you [good]?"
"I am good"
"Glad to hear"
"Hail, Mob!"
"Yes i know your good"

Ok so this goes well, however the next person comes up.

"Hail, Mob!"
"Yes i know your good"

Err.. whats going on? Problem with the communication between the qglobal table, and zone.exe. <shrug>

Or!

"Hail Mob"
"Hi Bob, have you got my item?"
You hand in item
Mob sets variable $item to value "2" indicating you have turned int he item.
"Asome! Tell me when you are [ready]"

But before you can say ready, Joe was watching and types
"i am ready"

Now he should get the respond
"Your not ready Joe, i didn't get an item from you"

But instead he gets.
Variable set to "1" indicating you are no longer ready, but it affectrs your variable and not his =/.
"Ok off you go!"

and Bob says "ready" and gets the
"Your not ready Bob, i didn't get an item from you.

erf nother problem.


SO! to avoid this a simple change is made to assigning variables

instead of

quest::targlobal("Var","1","D1",$mobid,$charid,$zoneid)
you would instead make the value personal.
eg.
quest::targlobal("Var",$charid + 1,"D1",$mobid,$charid,$zoneid);
This makes sure that Character 1 will have a value of 2, and character 2 will have a value of 3, thus when you check to see if they have the correct value you put.

If($var == $charid + 1)
{ }
this will make it so that if joe says "ready" and the variable returns 3 becuase hei s charid 2, it will not pass, but when Bob says "ready" it finds th e variable to equal $charid + 1 = 1 +1 = 2, and it works!.

that way you won't run into these types of errors =), and ofcourse you can use any combination with $charid. $charid + 2, $charid + 1423, etc.. it doesn't matter, however it ensures that you don't run into this issue.

Hope this helped =)

animepimp
07-23-2004, 03:16 AM
The reason you are seeing it appear for other characters is that you should probably use quest::setglobal([varname],[value],[options],[duration]); instead of targlobal if you want it to be private to that character. Just set the options field to 0 and it will be private to that character. Or use the other options for different combinations:

+--------+---------+---------+----------+
| value | npcid | player | zone |
+--------+---------+---------+----------+
| 0 | this | this | this |
| 1 | all | this | this |
| 2 | this | all | this |
| 3 | all | all | this |
| 4 | this | this | all |
| 5 | all | this | all |
| 6 | this | all | all |
| 7 | all | all | all |
+--------+---------+---------+----------+

Cisyouc
07-23-2004, 11:15 AM
Code:
quest::targlobal("Var",$charid + 1,"D1",$mobid,$charid,$zoneid);

This makes sure that Character 1 will have a value of 2, and character 2 will have a value of 3, thus when you check to see if they have the correct value you put. WOW! I didn't try it yet, but that is very clever :D Thanks =)

Cisyouc
07-23-2004, 11:41 AM
Code:
quest::targlobal("Var",$charid + 1,"D1",$mobid,$charid,$zoneid);

This makes sure that Character 1 will have a value of 2, and character 2 will have a value of 3, thus when you check to see if they have the correct value you put. WOW! I didn't try it yet, but that is very clever :D Thanks =)

After looking at it, its still not probably going to work. Well, ill try it anyway. Heres what I have.
sub EVENT_SAY
{
if($text=~/hail/i)
{
if($solusek == "")
{
quest::say("Hello, would you like to [help] me? (NEW)");
}
elsif($solusek == $charid + 1)
{
quest::say("Thanks for assisting me!");
}
}
if($text=~/help/i)
{
if($solusek == "")
{
quest::targlobal("solusek",$charid + 1,"Y5",$mobid,$charid,$zoneid);
quest::me("You have recieved a character flag!");
}
elsif($solusek == $charid + 1)
{
quest::say("You've already assisted me!!");
}
}
}

Update Didnt work!!! :x :x :x :x :x

Cisyouc
07-23-2004, 11:44 AM
The reason you are seeing it appear for other characters is that you should probably use quest::setglobal([varname],[value],[options],[duration]); instead of targlobal if you want it to be private to that character. Just set the options field to 0 and it will be private to that character. Or use the other options for different combinations:

+--------+---------+---------+----------+
| value | npcid | player | zone |
+--------+---------+---------+----------+
| 0 | this | this | this |
| 1 | all | this | this |
| 2 | this | all | this |
| 3 | all | all | this |
| 4 | this | this | all |
| 5 | all | this | all |
| 6 | this | all | all |
| 7 | all | all | all |
+--------+---------+---------+----------+Tried it, and it didnt work.