PDA

View Full Version : Another "Quest"ion


Neiv
07-18-2008, 06:52 PM
Is it possible (through some magic of global quest) to increase a stat for all players who share the same faction_id? I have a sort of "kingdoms" game in which there are several kingdoms associated with their own faction. When a player finds a certain item and turns it in to the king of that faction, several things happen:

1. Reinforcement guards, soldiers, etc., are spawned in and around the kingdom to protect it from other factions coming in and taking the item.

2. The character who turns the item in is awarded enough faction points to make him an ally, he is rewarded with enough xp to level at mid 30s, and he earns 5k plat.

Both of these work fine. Now I want to do the following:

To encourage the concept of factions, and to prompt players to organize their respective factions to "retake" the item for their own kingdom, I want to automatically increase the stats of all players with an ally faction of the kingdom who has the item. I'd like this to happen at item turn-in, and to maintain that increase until the item is taken from that king by another faction and given to their king. At that point I'd like to stats to go back to normal for the first faction, and increase stats for all players in the second faction once the item is turned into their king.

As long as a player's kingdom "owns" the item, he is advantaged with bonus stats. That motivates players of that faction to defend their kingdom, because once their king loses the item, they lose the bonus. It also motivates players of other factions to organize raids against the kingdom who holds the item.

Can this be done?

Please say yes. :)

ChaosSlayer
07-18-2008, 11:11 PM
i would guess NO =)
sorry

a remote alternative is to have a item which coudl be given out by your king to any player who has ally faction with him which has nice stats on it, but make item NO RENT

this means every time player logs out- items poof, but player can get it again as long as his faction remains ally and the king curently has a special flag set to meet your condition where the king has HIS item.

if kings item is taken away he stops giving out player bonus items untill kings item has been returned

Neiv
07-19-2008, 10:26 AM
Okay, that might work. The only potential problem I can see is that each player would have to make a trip to the kingdom to get this item each time he logs in--and these kingdoms are in the middle of nowhere. I suppose a portal would remedy that, but perish the thought! Portals are anathema in my world (as is spell casting).

Here's another thought. Could I place an npc of each allied faction in the major cities, have them hand out this item as a vicar of the king, and then, once the Item is taken from the king by another faction, the king sends some kind of quest::signal to all the vicars of the world to stop handing out items? Do global quests work that way (I have never used them).

ChaosSlayer
07-19-2008, 10:54 AM
you won't need to signal them - specialy since signaling does not work zone to zone

you simply have vicars to check for same global variable flag as king would

Neiv
07-19-2008, 12:30 PM
you won't need to signal them - specialy since signaling does not work zone to zone. you simply have vicars to check for same global variable flag as king would
How would I go about creating this flag?

ChaosSlayer
07-20-2008, 01:26 AM
by flag I mean global variable, which I belive you allready using for your event with King, no?

Striat
07-20-2008, 11:41 PM
easiest way is probably to use player quest and a spell. For example, call if blessing of the kings with the stat buff. then, have it check for faction and/or global. With a global of "FactionA" (triggered with the turn in), but also the option of having FactionB and FactionC(not triggered), let the spell = 9000 in this example and faction_id = 600, 601, and 602 respectively:

player.pl in template folder

sub EVENT_ENTERZONE {
quest::settimer("check",1);
}

sub EVENT_TIMER {
my $factioncheck = undef;
if ($qglobals{kingdomfaction} ) { #global is defined
if ($qglobals{kingdomfaction} eq "FactionA") { #FactionA has control
$factioncheck = $client->GetCharacterFaction(600);
if ($factioncheck >= 850) { #FactionA and character faction over 850
if (!$client->FindBuff(9000)) { #No Buff? Then cast
quest::selfcast(9000);
}
}
else {
if ($client->FindBuff(9000)) { #Has buff but not enough faction. Fade buff
$client->BuffFadeBySpellID(9000);
}
}
}
elsif ($qglobals{kingdomfaction} eq "FactionB") {
$factioncheck = $client->GetCharacterFaction(601);
if ($factioncheck >= 850) { #FactionB and character faction over 850
if (!$client->FindBuff(9000)) { #No Buff? Then cast
quest::selfcast(9000);
}
}
else {
if ($client->FindBuff(9000)) { #Has buff but not enough faction. Fade buff
$client->BuffFadeBySpellID(9000);
}
}
}
elsif($qglobals{kingdomfaction} eq "FactionC") {
$factioncheck = $client->GetCharacterFaction(602);
if ($factioncheck >= 850) { #FactionA and character faction over 850
if (!$client->FindBuff(9000)) { #No Buff? Then cast
quest::selfcast(9000);
}
}
else {
if ($client->FindBuff(9000)) { #Has buff but not enough faction. Fade buff
$client->BuffFadeBySpellID(9000);
}
}
}
}
else {
if ($client->FindBuff(9000)) { #Global not set but has buff
$client->BuffFadeBySpellID(9000);
}
}
}

Variations could also be used such as checking a player's global value (pledging alliance to a kingdom) or for an item. Several possibilities. If that doesn't work for you, let me know.

Another possibility is to use the quest::setstat command (I think that is it), but that could be more tricky.

The other possibility that I know of would simply be using a database query and updating values in the quest script (or adding a command). I really do not think that is optimal. It'd have the query in it though as UPDATE character format for typical sql update. I think you'd have to update blob file so could be a tad bit tricky. If you really really wanted to do it this way, let me know and I'll help you;p I do suggest one of the other methods though.

Edited--Since you mentioned you haven't really used quest globals, you'd need to have the hand in trigger the "flag". So in your king script when a player turns in the item, you would need to do like a quest::setglobal("kingdomfaction","FactionA",7,"F") in your event turn-in where FactionA is the value of the variable (just that it is defined) and 7 is for all players for the variable named kingdomfaction.

Neiv
07-22-2008, 07:30 AM
Thanks again. Will try this out.

Neiv
07-25-2008, 12:16 AM
Striat,

The spell approach may be a good option if I can put some kind of perma status on it (I have not worked much with spells since no PC on my server will be able to cast them).

Btw, does the concept of pledging to a deity use a different function than granting a ton of faction using quest::faction()?
you would need to do like a quest::setglobal("kingdomfaction","FactionA",7,"F" ) in your event turn-in where FactionA is the value of the variable (just that it is defined) and 7 is for all players for the variable named kingdomfaction.
I'm not sure I understand all this. I know what the first variable means. What does "F" stand for? And why does "7" stand for players?

Striat
07-25-2008, 08:11 PM
Striat,

The spell approach may be a good option if I can put some kind of perma status on it (I have not worked much with spells since no PC on my server will be able to cast them).I haven't done a ton of test work lately. I'd recommend you use Bleh and Ailia's spell editor from the forums to make new spells. I believe you can set a function that prevents a buff from being dispelled. Perhaps treating it as a debuff. To be honest, however, I am not completely sure off the top of my head. I just know it can be done without too much trouble. To do this, you'll have to distribute your custom spells_us.txt file to your players.

That said, what my player.pl script really does is check to see if a player should have the buff. If it doesn't it'll immediately strip the buff. If the player doesn't have the buff (say they log in and their faction has taken over), they will receive the buff.


Btw, does the concept of pledging to a deity use a different function than granting a ton of faction using quest::faction()?


I'm not sure I understand all this. I know what the first variable means. What does "F" stand for? And why does "7" stand for players?F stands for forever. So, the global will last forever or until it is replaced by a different value. 7 refers to the global table at the bottom of http://www.eqemulator.net/wiki/wikka.php?wakka=QuestTutorial. 7 corresponds to npcid-all,player-all,zone-all. This means the global is set to the given value for all npcs, all zones, and all players.

Striat
07-25-2008, 08:34 PM
Since my post got screwed up and I cannot edit, here goes.

deity is normally an aspect of faction. So, I wouldn't say it is the same thing. You could always make a faction called cazic thule or something (this one does already exist) and make it work practically the same though.

And on the last thing,

quest::setglobal("kingdomfaction","FactionA",7,"F" )

kingdomfaction is the global's name. FactionA is the value. 7 corresponds to who the variable will affect. You could use any number 1-7 from the table in the link mentioned above. However, 7 means the global variable kingdomfaction is set to FactionA for all players and all npcs in all zones. And again, F is the time variable. I normally use F for forever, but you can use other things such as "Y5" for 5 years if you really want to.

So, what exactly does the 7 mean?

I made an npc named Inny in hateplaneb. I made an npc named cazzy in fearplane. I gave them the exact same script:
if($text=~/hail/i){
quest::say("Hi $name. kingdomfaction is set to $qglobals{kingdomfaction}");
}

When Striat hailed Inny in hateplaneb, he sets kingdomfaction is set to FactionA. Then, Rondo hailed Cazzy in fearplane. Again, kingdomfaction is set to FactionA.

Next, I used 5 instead of 7. This is npcs-all, players-this player only, zone-all zones. I completed the initial quest with Striat. I hail Cazzy, I get the same response as above. Same response with Izzy.

Then, I use Rondo. I hail the npcs and he gets a blank value because the value is only defined for Striat. Hope that clears that aspect up a little.

Neiv
07-26-2008, 06:08 PM
This may be a bit beyond my current ability. I'm not sure I understand the precise relationship between the player.pl (does this reside in the zone folder btw, or somewhere else?) the king's script, the quest::setglobal("kingdomfaction","FactionA",7,"F") statement (is this part of the king's script?), and the quest::say in your most recent note (is this for the player to get the buff or is it to initiate the kingdom faction?).

Striat
08-01-2008, 08:36 PM
This may be a bit beyond my current ability. I'm not sure I understand the precise relationship between the player.pl (does this reside in the zone folder btw, or somewhere else?)
You'd put it in templates folder. It is the fairly new player quest system. Look it up in the wiki under quests section.


the king's script,
This would just be the npc that triggers current faction setting


the quest::setglobal("kingdomfaction","FactionA",7,"F") statement (is this part of the king's script?),
Yes



and the quest::say in your most recent note (is this for the player to get the buff or is it to initiate the kingdom faction?).

You can ignore that;p It's just for checking what the global value is set to. It doesn't really need to be in a script for the script to function

Neiv
08-03-2008, 10:35 PM
Striat, I haven't yet tried your solution but will shortly. Thanks for responding. Didn't want you to think I was ignoring; just trying to get other quests to work at the same time.

Neiv
08-17-2008, 12:21 AM
easiest way is probably to use player quest and a spell. For example, call if blessing of the kings with the stat buff. then, have it check for faction and/or global. With a global of "FactionA" (triggered with the turn in), but also the option of having FactionB and FactionC(not triggered), let the spell = 9000 in this example and faction_id = 600, 601, and 602 respectively:

player.pl in template folder

sub EVENT_ENTERZONE {
quest::settimer("check",1);
}

sub EVENT_TIMER {
my $factioncheck = undef;
if ($qglobals{kingdomfaction} ) { #global is defined
if ($qglobals{kingdomfaction} eq "FactionA") { #FactionA has control
$factioncheck = $client->GetCharacterFaction(600);
if ($factioncheck >= 850) { #FactionA and character faction over 850
if (!$client->FindBuff(9000)) { #No Buff? Then cast
quest::selfcast(9000);
}
}
else {
if ($client->FindBuff(9000)) { #Has buff but not enough faction. Fade buff
$client->BuffFadeBySpellID(9000);
}
}
}
elsif ($qglobals{kingdomfaction} eq "FactionB") {
$factioncheck = $client->GetCharacterFaction(601);
if ($factioncheck >= 850) { #FactionB and character faction over 850
if (!$client->FindBuff(9000)) { #No Buff? Then cast
quest::selfcast(9000);
}
}
else {
if ($client->FindBuff(9000)) { #Has buff but not enough faction. Fade buff
$client->BuffFadeBySpellID(9000);
}
}
}
elsif($qglobals{kingdomfaction} eq "FactionC") {
$factioncheck = $client->GetCharacterFaction(602);
if ($factioncheck >= 850) { #FactionA and character faction over 850
if (!$client->FindBuff(9000)) { #No Buff? Then cast
quest::selfcast(9000);
}
}
else {
if ($client->FindBuff(9000)) { #Has buff but not enough faction. Fade buff
$client->BuffFadeBySpellID(9000);
}
}
}
}
else {
if ($client->FindBuff(9000)) { #Global not set but has buff
$client->BuffFadeBySpellID(9000);
}
}
}

I'm just now starting to experiment with this. Is the settimer function even necessary in this? Can't I just put the script that appears under the TIMER event under the ENTERZONE event instead? I don't even see an "if($timername eq "check")" statement that would trigger the timer. Or am I just missing something?

Striat
08-18-2008, 04:47 PM
I'm just now starting to experiment with this. Is the settimer function even necessary in this? Can't I just put the script that appears under the TIMER event under the ENTERZONE event instead? I don't even see an "if($timername eq "check")" statement that would trigger the timer. Or am I just missing something?
The point of a looped timer would be so that if faction or whatever changed while players are killing in a zone, they'd be stripped of buffs. Or if their faction takes over, they'd be given the buff. That is why I used a timer in my example.

On the if($timer eq "check") thingy...You can add it. But, you don't have to. if a timer check is not specified (such as in my script under EVENT_TIMER as you mention), it should trigger everything under EVENT_TIMER.

Neiv
08-18-2008, 08:51 PM
The point of a looped timer would be so that if faction or whatever changed while players are killing in a zone, they'd be stripped of buffs. Or if their faction takes over, they'd be given the buff. That is why I used a timer in my example. On the if($timer eq "check") thingy...You can add it. But, you don't have to. if a timer check is not specified (such as in my script under EVENT_TIMER as you mention), it should trigger everything under EVENT_TIMER.
I see. Thanks. Now that I have it complete it's crashing the zone, so I'm sure I've misinterpreted something. Here is the entire script:
sub EVENT_ENTERZONE
##checks is player has item; if so, is added to hate list of NPCID 999243
##if not, checks for kingdom faction
{
if(plugin::check_hasitem($client, 13732))
{
$client->SetPVP(1);
quest::settimer("aggro",20);
}

else
{
quest::settimer("check",1);
}
}


sub EVENT_TIMER
{
if($timername == "aggro")
{
my $guard_one = $entity_list->GetMobByNpcTypeID(999243);

if ($guard_one)
{
my $hate_guard_one = $guard_one->CastToNPC();
$hate_guard_one->AddToHateList($client, 1);
}
quest::stoptimer("aggro");
}
elsif($timername == "check")

{

my $factioncheck = undef;
if ($qglobals{kingdomfaction})
{ #global is defined

# #FactionA
if ($qglobals{kingdomfaction} eq "FactionA")
{ #FactionA has control
$factioncheck = $client->GetCharacterFaction(19927);
if ($factioncheck >= 850)
{ #FactionA and character faction over 850
if (!$client->FindBuff(9000))
{ #No Buff? Then cast
quest::selfcast(9000);
}
}
else
{
if ($client->FindBuff(9000))
{ #Has buff but not enough faction. Fade buff
$client->BuffFadeBySpellID(9000);
}
}
}

# #FactionB faction
elsif ($qglobals{kingdomfaction} eq "FactionB")
{ #FactionB has control
$factioncheck = $client->GetCharacterFaction(19928 ); #space added to prevent emoticon in post, does not appear in script
if ($factioncheck >= 850)
{ #FactionB and character faction over 850
if (!$client->FindBuff(9000))
{ #No Buff? Then cast
quest::selfcast(9000);
}
}
else
{
if ($client->FindBuff(9000))
{ #Has buff but not enough faction. Fade buff
$client->BuffFadeBySpellID(9000);
}
}
}

# #FactionC faction
elsif($qglobals{kingdomfaction} eq "FactionC")
{ #FactionC has control
$factioncheck = $client->GetCharacterFaction(19930);
if ($factioncheck >= 850)
{ #FactionC and character faction over 850
if (!$client->FindBuff(9000))
{ #No Buff? Then cast
quest::selfcast(9000);
}
}
else
{
if ($client->FindBuff(9000))
{ #Has buff but not enough faction. Fade buff
$client->BuffFadeBySpellID(9000);
}
}
}

# #FactionD faction
elsif($qglobals{kingdomfaction} eq "FactionD")
{ #FactionD has control
$factioncheck = $client->GetCharacterFaction(19931);
if ($factioncheck >= 850)
{ #FactionD and character faction over 850
if (!$client->FindBuff(9000))
{ #No Buff? Then cast
quest::selfcast(9000);
}
}
else
{
if ($client->FindBuff(9000))
{ #Has buff but not enough faction. Fade buff
$client->BuffFadeBySpellID(9000);
}
}
}
else
{
if ($client->FindBuff(9000))
{ #Global not set but has buff
$client->BuffFadeBySpellID(9000);
}
}
}
}
}


I ran this through a perl cmd line and it returned no errors. But when I put it in the quest/zone folder it crashed the zone. Any thoughts?

Congdar
08-18-2008, 10:13 PM
the eqemu_quest_zone_3500.log file might have some clues (3500 would be a different number for you).

Deimos
08-18-2008, 11:10 PM
this code is too messy for me to really see much ><

If the zone is crashing, that's either a loop or a timer issue, and seeing as you have no loops, it's probably your timer.

Then again, considering it only goes once a second, I don't see how this would cause it.. oh well.

I agree, check the log files and that'll dish out some clues.

Also, check the folder size of the logs. If it's a loop or timer issue, it's going to be 300+ megs. Yea, I've had some evil typos in loops and have had 250 gig log folders ;o.... mmm....

Oh well, hope you find what's causing it. If not, put the code up on rafb or something so everyone can see color coding and indents that way your code is not so messy : D.

Neiv
08-19-2008, 10:48 PM
Here's the RAFB URL (http://rafb.net/p/9yzbXz46.html)to the script. You'll notice I placed a quest::emote in the EVENT_ENTERZONE and in the first faction check under the "check" timer. When I enter a zone, I receive the first emote (which tells me it makes it past the point of triggering the timer), but not the second one. By the way, the script no longer crashes the zone. But neither does it cast the buff on my character (char has 1000 faction with FactionA).

Neiv
08-20-2008, 11:06 PM
I just reread Striat's original post. So this player.pl is supposed to go in the templates folder?

Neiv
08-21-2008, 11:51 AM
Also . . .
Edited--Since you mentioned you haven't really used quest globals, you'd need to have the hand in trigger the "flag". So in your king script when a player turns in the item, you would need to do like a quest::setglobal("kingdomfaction","FactionA",7,"F" ) in your event turn-in where FactionA is the value of the variable (just that it is defined) and 7 is for all players for the variable named kingdomfaction.
Is "FactionA" in the function above a reference to the faction number, or is it rather the name I have assigned to the faction in the faction-check script?