Log in

View Full Version : Q&A Thread


Kingly_Krab
06-07-2018, 03:55 PM
Have any questions, issues, or concerns about the way Lua/Perl quests work? Feel free to ask here. In my time working with EQEmulator I've written probably 1,000,000 different scripts in dozens of different formats and languages. If you are stuck on a script or have an idea you can't put in to script form, ask here. I'll either write you a mockup, solve your issue, or give you an idea as to what you're doing incorrectly.

TL;DR: I'm bored of not working on a server and I want to help the new server operators who may not know the ins and outs of Perl/Lua.

swansona65
06-08-2018, 09:18 AM
I am trying to create a script for NPC's that will teleport people to tier zones.. So you would hail the NPC and he would teleport you to said zone. I have no idea where to even start, thank you for your help.

Kingly_Krab
06-08-2018, 11:22 AM
Take a look here (http://www.eqemulator.org/forums/showthread.php?t=41456).

swansona65
06-08-2018, 02:57 PM
Thanks man! Can you give me dumbed down version with only a hail and port to a specific zone name i can fill in. I will deal with flags later.

Castious
06-16-2018, 02:07 PM
A way to limit the amount of damage able to be done via melee to a NPC. Like say I only want players to be able to hit something for 20 damage max.

Huppy
09-06-2018, 08:09 PM
Been trying to figure out what I am missing here with simple script. The text response works, but not the follow.


sub EVENT_SAY {

my $gather = $entity_list->GetClientByCharID($charid);

if($text=~/hail/i) {
quest::say("I'm with you $name and following.");
quest::follow($gather);
}
}

Akkadius
09-06-2018, 08:28 PM
Try using $name in quest::follow - or $gather->GetCleanName(), but $name should suffice in your given example

Huppy
09-06-2018, 08:42 PM
Try using $name in quest::follow - or $gather->GetCleanName(), but $name should suffice in your given example

Ok, I will give that a shot. I did try using GetClientByName($name) as well as a few other variables, but I will see what happens with your suggestion. Thank You :)

Almusious
09-07-2018, 08:41 AM
Ok, I will give that a shot. I did try using GetClientByName($name) as well as a few other variables, but I will see what happens with your suggestion. Thank You :)

In your quest::follow is where you try $name he means

You shouldn't have to get the client object, as it is the initiator of EVENT_SAY, so just $client would suffice

Ive always used an ID of a pc/npc, give it a try:


sub EVENT_SAY {
if($text=~/hail/i)
{
quest::say("I'm with you $name and following.");
quest::follow($userid);
}
}

Huppy
09-07-2018, 09:38 AM
Ive always used an ID of a pc/npc, give it a try:


sub EVENT_SAY {
if($text=~/hail/i)
{
quest::say("I'm with you $name and following.");
quest::follow($userid);
}
}


Hey Almuscious, thank you, that little sample works like a charm :)

I'd already tried a few variables with the quest::follow before I even posted the question, including $name and $client, etc.

My intentions for this little task, was just for any player that hails the NPC, it will start to follow.

I've already got scripts running with NPC's following other NPC's with id's but this was my first crack at a random PC follow.

I was going through everything on the wiki with entities, etc., and had no luck, but I sometimes I overlook the obvious, lol

EDIT: This works good with an EVENT_ENTER as well. I set the proximity so all you have to do is run by and it clings to you, lol

Almusious
09-07-2018, 10:25 AM
Hey Almuscious, thank you, that little sample works like a charm :)

I'd already tried a few variables with the quest::follow before I even posted the question, including $name and $client, etc.

My intentions for this little task, was just for any player that hails the NPC, it will start to follow.

I've already got scripts running with NPC's following other NPC's with id's but this was my first crack at a random PC follow.

I was going through everything on the wiki with entities, etc., and had no luck, but I sometimes I overlook the obvious, lol

EDIT: This works good with an EVENT_ENTER as well. I set the proximity so all you have to do is run by and it clings to you, lol

Before the recent work on the eqemu wiki I would often turn to the source (embparser.cpp, etc.) to see what what expects as data but keep this in your arsenal, it will likely be your go to:

https://github.com/EQEmu/Server/wiki/Perl-API

If we look up the quest::follow we'll see it expects an entity id rather than the object itself

quest::follow(int entity_id, [int distance = 10])


Consequently you can define a following distance with the below


quest::follow($userid, 50);


otherwise

quest::follow($userid);


without a distance defined it will default to 10

Happy coding

Huppy
09-07-2018, 10:51 AM
Thanks a lot Almusious. Just thought I would mention. Did some testing with the proximity trigger and a 2nd PC wandering by.
If Player A has the NPC following and Player B happens to come along, NPC picks up the new player and follows. It's funny, lol

Almusious
09-07-2018, 11:14 AM
Thanks a lot Almusious. Just thought I would mention. Did some testing with the proximity trigger and a 2nd PC wandering by.
If Player A has the NPC following and Player B happens to come along, NPC picks up the new player and follows. It's funny, lol


sub EVENT_SAY {
if ($text=~/hail/i and !$entity->GetEntityVariable("master"))
{
$entity->SetEntityVariable("master", $charid);
quest::say("I'm with you $name and following.");
quest::follow($userid);
}
elsif ($text=~/leave/i and $entity->GetEntityVariable("master") == $charid)
{
quest::say("Fine $name! Be all alone in your travels...");
$entity->SetEntityVariable("master", 0); # just in case it doesnt poof i guess
quest::depop();
}
}

Huppy
09-08-2018, 08:53 AM
sub EVENT_SAY {
if ($text=~/hail/i and !$entity->GetEntityVariable("master"))
{
$entity->SetEntityVariable("master", $charid);
quest::say("I'm with you $name and following.");
quest::follow($userid);
}
elsif ($text=~/leave/i and $entity->GetEntityVariable("master") == $charid)
{
quest::say("Fine $name! Be all alone in your travels...");
$entity->SetEntityVariable("master", 0); # just in case it doesnt poof i guess
quest::depop();
}
}


Hey Almusious, I just got around to testing this out, this morning. I couldn't get any response out of the NPC with it.

The initial hail>follow script will serve it's purpose, but thinking ahead, would open up an exploit with conflicting players.

Could end up with 2 players (or more) spamming the npc with "Hail's" to steal it away. Would be funny to watch, lol

Huppy
09-09-2018, 02:10 PM
I almost forgot about another question I had regarding this follow thing and wondering if an idea I had was possible.

For example, NPC starts following player, but then the player is moving too fast, creating a big distance between them.

Is there a way to set an "sfollow" when a certain distance happens ? Like if the player gets too far away, the NPC quits ?

Almusious
09-09-2018, 03:24 PM
Hey Almusious, I just got around to testing this out, this morning. I couldn't get any response out of the NPC with it.

The initial hail>follow script will serve it's purpose, but thinking ahead, would open up an exploit with conflicting players.

Could end up with 2 players (or more) spamming the npc with "Hail's" to steal it away. Would be funny to watch, lol

The code is all fubared, wasn't paying much attention, for that I'm sorry. $entity should be just that, so $npc or $client, I would probably put the entity variable on the $npc, since it's getting depoped. Speaking of which that is off too, quest::depop($npc->GetNPCTypeID()) is how that line should be, according to the wiki.

Heck those conditionals look off as well, mustve been the ambien, sorry.

Almusious
09-09-2018, 03:26 PM
I almost forgot about another question I had regarding this follow thing and wondering if an idea I had was possible.

For example, NPC starts following player, but then the player is moving too fast, creating a big distance between them.

Is there a way to set an "sfollow" when a certain distance happens ? Like if the player gets too far away, the NPC quits ?

I didn't immediately see a means to sever a follow. Is why either depop'ing it or maybe repopping with timer. Now without setting a "master" (owner), it could be a bit of an NPC hot potato type of quest heh.

Huppy
09-09-2018, 03:43 PM
Thanks for your reply. Just to clarify what I have in mind, the NPC won't be depopping. Upon the destination, it will be killed by another NPC, lol.

I've already been testing that with with an EVENT_ENTER, on arrival, an NPC immediately attacks the following one. Works great so far.

I also added in an if(plugin::check_hasitem(xxxx)) to the quest::follow which also worked out good.

Almusious
09-09-2018, 03:47 PM
I almost forgot about another question I had regarding this follow thing and wondering if an idea I had was possible.

For example, NPC starts following player, but then the player is moving too fast, creating a big distance between them.

Is there a way to set an "sfollow" when a certain distance happens ? Like if the player gets too far away, the NPC quits ?

You could set a timer when you initiate the follow, then use an event timer like:


sub EVENT_TIMER
{
if ($npc->CalculateDistance($entity_list->GetClientByCharID($npc->GetEntityVariable("master"))->GetX(),
$entity_list->GetClientByCharID($npc->GetEntityVariable("master"))->GetY(),
$entity_list->GetClientByCharID($npc->GetEntityVariable("master"))->GetZ()) > 20)
{
quest::sfollow();
}
}


This assumes you replaced $entity in the code earlier posted with $npc.

Huppy
09-09-2018, 04:05 PM
You could set a timer when you initiate the follow, then use an event timer like:

That could be something that may help with my intentions here. You see, I am looking at a possible exploit with the follow event.

A player could end up using /warp and then wait for the NPC to arrive. That's why I thought a distance limit would help with that.

JimB_1958
10-26-2018, 11:40 AM
Weird thing:

I want to fire an event in player.pl when the player takes damage from a mob.

Kind of like damage shields work.

I would prefer to get the id of the mob that did the damage, but that is not 100% needed.

Thank you for any assistance.

Secrets
10-26-2018, 12:15 PM
Weird thing:

I want to fire an event in player.pl when the player takes damage from a mob.

Kind of like damage shields work.

I would prefer to get the id of the mob that did the damage, but that is not 100% needed.

Thank you for any assistance.

If you're doing that, do it in LUA. There are serious performance indications to doing this.

superpally1
10-29-2018, 09:50 AM
Hey guys, I've got a quick question to. I have searched and been unsuccessful in finding a way to do this. Is there a way to script a say link into guild chat and/or raid chat? I think I can do group chat with message group but I can not find a function for guild/raid. I've been working on an instancing script and I want to be able to send the say link to enter the instances to group,guild, and raid chat. Message 258 for example says group but it doesn't actually say it in group for the other group members.

Kingly_Krab
10-29-2018, 10:00 AM
quest::gmsay(message, color_id, send_to_world?, guild_id, min_status);

superpally1
10-29-2018, 10:18 AM
quest::gmsay(message, color_id, send_to_world?, guild_id, min_status);

I didn't think about that. Thank you. I can see how to use this in guild chat now but how could I use it with raid chat?

Kingly_Krab
10-29-2018, 12:08 PM
You can use a loop and iterate through group members if necessary. I’m at work, otherwise I’d give you an example.

superpally1
10-29-2018, 06:32 PM
gotcha, thankyou sir.

Ydiss
01-15-2019, 02:04 PM
Hey, I think this is my fourth post here. Been a member since 2009 hah.

I've started developing for THF recently and have been enjoying it loads. I'm just hitting a brick wall with this one particular (apparently non-existent) function.

I'm attempting to get the NPC's hp_regen value (I know I can modify it easily enough) but can't find the command for this anywhere on the ultimate perl reference (or anywhere else).

I checked the perl source and searched for "hp" but couldn't find it. It seems this is also the case for mana_regen, though I don't currently need that.

I want to make changes to npc regen but without a way to read/get the current value, that severely limits my ability to do anything clever with it (i.e. I can pretty much just hard code it).

What I want to do is reduce the hp_regen when players do something. Without the ability to read what it is currently, I imagine I'd need to use qglobals to track each npc's status (from spawn) and then hard code a sequence of conditions for it and that's just horrid.

I'd rather not do that. It seems literally every other editable stat for NPCs can be read except regen :) Am I missing something?

Any help would be amazing. Thanks.

Almusious
01-15-2019, 02:54 PM
https://github.com/EQEmu/Server/blob/0ad43977bf94e3a2ca83966f7fc9ba5592bb2a54/zone/npc.cpp#L2307



quest::modifynpcstat("hp_regen",xxx);


or


$npc->ModifyNPCStat("hp_regen",xxx);


Sorry, I just re-read what you had written. You wish to know how to "get". I too cannot find something in place for that, but:


sub PrepareEntityVariables
{
my @zone_npcs = $entity_list->GetNPCList();
my $dbh = plugin::LoadMysql();
foreach $individual_npc (@zone_npcs)
{
if (not $individual_npc->GetEntityVariable("regenset"))
{
my $sth = $dbh->prepare("
SELECT `hp_regen_rate`, `mana_regen_rate`
FROM npc_types
WHERE (`id` = ?) LIMIT 1
");
$sth->bind_param(1,$individual_npc->GetNPCType());
$sth->execute();
@row = $sth->fetchrow_array();
$individual_npc->SetEntityVariable("hpregen", $row[0]);
$individual_npc->SetEntityVariable("manaregen", $row[1]);
$individual_npc->SetEntityVariable("regenset",1);
}
}
}


Try the above, it may have a syntax error or two, I'm not in a position to compile it, but should give you an idea just the same. The reason for actually setting an entity variable of "regenset" is in the case of either hpregen or manaregen equaling zero (legitimately).

Ydiss
01-15-2019, 07:28 PM
https://github.com/EQEmu/Server/blob/0ad43977bf94e3a2ca83966f7fc9ba5592bb2a54/zone/npc.cpp#L2307



quest::modifynpcstat("hp_regen",xxx);


or


$npc->ModifyNPCStat("hp_regen",xxx);


Sorry, I just re-read what you had written. You wish to know how to "get". I too cannot find something in place for that, but:


sub PrepareEntityVariables
{
my @zone_npcs = $entity_list->GetNPCList();
my $dbh = plugin::LoadMysql();
foreach $individual_npc (@zone_npcs)
{
if (not $individual_npc->GetEntityVariable("regenset"))
{
my $sth = $dbh->prepare("
SELECT `hp_regen_rate`, `mana_regen_rate`
FROM npc_types
WHERE (`id` = ?) LIMIT 1
");
$sth->bind_param(1,$individual_npc->GetNPCType());
$sth->execute();
@row = $sth->fetchrow_array();
$individual_npc->SetEntityVariable("hpregen", $row[0]);
$individual_npc->SetEntityVariable("manaregen", $row[1]);
$individual_npc->SetEntityVariable("regenset",1);
}
}
}


Try the above, it may have a syntax error or two, I'm not in a position to compile it, but should give you an idea just the same. The reason for actually setting an entity variable of "regenset" is in the case of either hpregen or manaregen equaling zero (legitimately).

Thanks, that's really helpful. Yes, I'd need to check for zero anyway.

Will see if I can get it to work.

Akkadius
01-16-2019, 04:21 AM
Hey, I think this is my fourth post here. Been a member since 2009 hah.

I've started developing for THF recently and have been enjoying it loads. I'm just hitting a brick wall with this one particular (apparently non-existent) function.

I'm attempting to get the NPC's hp_regen value (I know I can modify it easily enough) but can't find the command for this anywhere on the ultimate perl reference (or anywhere else).

I checked the perl source and searched for "hp" but couldn't find it. It seems this is also the case for mana_regen, though I don't currently need that.

I want to make changes to npc regen but without a way to read/get the current value, that severely limits my ability to do anything clever with it (i.e. I can pretty much just hard code it).

What I want to do is reduce the hp_regen when players do something. Without the ability to read what it is currently, I imagine I'd need to use qglobals to track each npc's status (from spawn) and then hard code a sequence of conditions for it and that's just horrid.

I'd rather not do that. It seems literally every other editable stat for NPCs can be read except regen :) Am I missing something?

Any help would be amazing. Thanks.

If you're talking about inflated hp_regen rates in one of the recent source releases, make sure you are updated to the latest source as it includes a database update that resolves this issue

Ydiss
01-16-2019, 05:50 AM
If you're talking about inflated hp_regen rates in one of the recent source releases, make sure you are updated to the latest source as it includes a database update that resolves this issue

Hi Akkadius

Thanks for your reply. It's not related to that (I actually wanted to control regen rates as part of a quest).

I've actually thought of a workaround this morning. I can hijack another readable npc stat and use that to control the hp_regen value. For example, I can use charisma.

I just need to initially set the npc's cha to the same value as the hp_regen value, divided by 1000. Then I can use getCHA() and modify cha (eg -10) and apply that value to modify hp_regen (*1000).

It should work in theory.