Log in

View Full Version : defaultCombat.pl


javewow
11-08-2012, 03:58 PM
I want to let all the fighting to stop NPC

Return to full HP

Don't know what to do

---------------------------------

sub EVENT_SPAWN
{

Plugin::setnexthpevent(1000);
}


sub EVENT_COMBAT
{
if ($combat_state = 1)
{
$npc->SetHP(9990000);
}
}

-------------------------------

copy---> plugins/defaultCombat.pl ????? HELP!!!

and for default.pl ?

c0ncrete
11-08-2012, 04:17 PM
you probably want to edit EVENT_COMBAT in plugins\default-actions.pl

any npc that has EVENT_COMBAT defined in their individual script won't use the default, so you'll have to edit all of them individually.

i don't know what you are trying to do with the call to setnexthpevent(), as it is unrelated to what you mentioned wanting to do.

$event_combat is set to 0 when an npc leaves combat.

using $npc->Heal() should set the npc's health to 100%.

javewow
11-08-2012, 09:13 PM
you probably want to edit EVENT_COMBAT in plugins\default-actions.pl

any npc that has EVENT_COMBAT defined in their individual script won't use the default, so you'll have to edit all of them individually.

i don't know what you are trying to do with the call to setnexthpevent(), as it is unrelated to what you mentioned wanting to do.

$event_combat is set to 0 when an npc leaves combat.

using $npc->Heal() should set the npc's health to 100%.

# Default-actions.pl
#
# Default actions to perform if the user performs particular actions on an NPC.

sub defaultSay
{
my $handled = plugin::nullzero(shift);
my $name = plugin::assocName();
my $text = plugin::val('$text');
my $mname = plugin::fixNPCName();
my $faction = plugin::val('$faction');
my $zonesn = plugin::val('$zonesn');
my $npc = plugin::val('$npc');
my $zoneln = plugin::cityName();

if (!$handled)
{
if ($mname=~/^Soulbinder\w/)
{
if($text=~/^hail/i)
{
quest::say("Greetings, ${name}. When a hero of our world is slain, their soul returns to the place it was last bound and the body is reincarnated. As a member of the Order of Eternity, it is my duty to [bind your soul] to this location if that is your wish.");
quest::doanim(29);

$handled = 1;
}
elsif (($text=~/bind my soul/i) || ($text=~/bind your soul/i))
{
quest::say("Binding your soul. You will return here when you die.");
quest::doanim(42);
quest::selfcast(2049);

$handled = 1;
}
}
elsif ($mname=~/^Guard\w/)
{
if ($faction > 5)
{
quest::me("$mname glowers at you dubiously.");

$handled = 1;
}
else
{
quest::say("Hail, $name! Pardon me. I am on duty, keeping $zoneln safe.");

$handled = 1;
}
}
elsif (($mname=~/^Merchant\w/) || ($mname=~/^Innkeep/) || ($mname=~/^Barkeep/))
{
if($text=~/^Hail/i)
{
quest::say("Welcome, $name! Why don't you browse through my selection of fine goods and pick out some things you like?");

$handled = 1;
}
}
}

if (($text=~/test money/i) && (plugin::val('$status') > 20))
{
quest::givecash(99, 99, 99, 99);
}
}

sub defaultItem
{
plugin::returnUnusedItems();
}

sub defaultDeath
{
my $handled = plugin::nullzero(shift);
my $mname = plugin::val('$mname');
my $zonesn = plugin::val('$zonesn');

if (!$handled)
{
if ($mname =~ /^(an\_)?orc(\_.+|)$/i) # Everything from 'orc' to 'an_orc_flibberty_gibbet', but not 'orchard_master', etc.
{
# Orc death

quest::say(
(($zonesn =~ /(g|l)faydark/) || ($zonesn eq 'crushbone')) ? plugin::random('You shall have all the Crushbone Orcs on your tail for my death!!') :
"DEBUG: $zonesn orc death!");

$handled = 1;
}
elsif ($mname =~ /^(a\_)?gnoll(\_.+|)$/i) # Everything from 'gnoll' to 'a_gnoll_flibberty_gibbet', but not 'gnollish', etc.
{
# Gnoll death

quest::say(
($zonesn =~ /^qey/i) ? plugin::random('DEBUG: Blackburrow gnoll death!!') :
"DEBUG: $zonesn (Non-Blackburrow) gnoll death!");
$handled = 1;
}
elsif ($mname =~ /^Guard/i)
{
# Guard death

my $city = plugin::cityName();

quest::say( ($city eq 'Kelethin') ? 'Kelethin guard death!' :
($city eq 'Felwithe') ? 'Felwithe guard death!' :
"DEBUG: $city guard death!" );

$handled = 1;
}
}
}

sub defaultSlay
{
my $handled = plugin::nullzero(shift);
my $mname = plugin::val('$mname');
my $zonesn = plugin::val('$zonesn');

if (!$handled)
{
if ($mname =~ /^Guard/i)
{
# Guard kills

# 25% chance for flavor text
if (int(rand(4)) == 0)
{
my $city = plugin::cityName();

quest::say(
($city eq 'Kelethin') ? 'For the protection of all Feir\'dal, there shall be no mercy for your kind.' :
($city eq 'Felwithe') ? 'Another one bites the dust.' :
"$city is a little bit safer now." );
}

$handled = 1;
}
}
}

sub EVENT_COMBAT
{
my $npc = plugin::val('$npc');
my $zonesn = plugin::val('$zonesn');

if ($event_combat = 0)
{
$npc->SetHP();
}
}
}
sub defaultCombat()
{
my $combat_state = plugin::val('$combat_state');
my $zonesn = plugin::val('$zonesn');
my $mname = plugin::val('$mname');

if ($combat_state == 1)
{
if ($zonesn =~ /^((l|g)faydark|crushbone)$/)
{
if ($mname =~ /^(an\_)?orc(\_.+|)$/i) # Everything from 'orc' to 'an_orc_flibberty_gibbet', but not 'orchard_master', etc.
{
}
}
}
}


return;

# Sample code to work from
my $random_result = int(rand(100));
if(($combat_state == 1) &&($random_result<=50)){
quest::say("Death!! Death to all who oppose the Crushbone orcs!!");
}else{
quest::say("You've ruined your lands. You'll not ruin mine!");
}


Help have a look whether this can all ZONE NPC????

c0ncrete
11-08-2012, 10:12 PM
sorry. i told you wrong. default-actions doesn't need an EVENT_COMBAT sub. you'd just need to edit defaultCombat() to suit your needs. additionally, i think you want to place default.pl directly in the quests directory for plugins\default-actions.pl to be used.

once that is done, this should do what you are wanting:

sub defaultCombat()
{
my $combat_state = plugin::val('$combat_state');
my $npc = plugin::val('$npc');

if ($combat_state == 0)
{
$npc->Heal();
}
}

i believe you still have to add the changes manually to every existing npc script as they won't use the default. i am not at a computer that i can test this out on at the moment.

javewow
11-09-2012, 01:09 AM
1:this file -default-actions.pl----copy to c:/peq/plugins/ + c:/peq/quests/plugins/


# Default-actions.pl
#
# Default actions to perform if the user performs particular actions on an NPC.

sub defaultSay
{
my $handled = plugin::nullzero(shift);
my $name = plugin::assocName();
my $text = plugin::val('$text');
my $mname = plugin::fixNPCName();
my $faction = plugin::val('$faction');
my $zonesn = plugin::val('$zonesn');
my $npc = plugin::val('$npc');
my $zoneln = plugin::cityName();

if (!$handled)
{
if ($mname=~/^Soulbinder\w/)
{
if($text=~/^hail/i)
{
quest::say("Greetings, ${name}. When a hero of our world is slain, their soul returns to the place it was last bound and the body is reincarnated. As a member of the Order of Eternity, it is my duty to [bind your soul] to this location if that is your wish.");
quest::doanim(29);

$handled = 1;
}
elsif (($text=~/bind my soul/i) || ($text=~/bind your soul/i))
{
quest::say("Binding your soul. You will return here when you die.");
quest::doanim(42);
quest::selfcast(2049);

$handled = 1;
}
}
elsif ($mname=~/^Guard\w/)
{
if ($faction > 5)
{
quest::me("$mname glowers at you dubiously.");

$handled = 1;
}
else
{
quest::say("Hail, $name! Pardon me. I am on duty, keeping $zoneln safe.");

$handled = 1;
}
}
elsif (($mname=~/^Merchant\w/) || ($mname=~/^Innkeep/) || ($mname=~/^Barkeep/))
{
if($text=~/^Hail/i)
{
quest::say("Welcome, $name! Why don't you browse through my selection of fine goods and pick out some things you like?");

$handled = 1;
}
}
}

if (($text=~/test money/i) && (plugin::val('$status') > 20))
{
quest::givecash(99, 99, 99, 99);
}
}

sub defaultItem
{
plugin::returnUnusedItems();
}

sub defaultDeath
{
my $handled = plugin::nullzero(shift);
my $mname = plugin::val('$mname');
my $zonesn = plugin::val('$zonesn');

if (!$handled)
{
if ($mname =~ /^(an\_)?orc(\_.+|)$/i) # Everything from 'orc' to 'an_orc_flibberty_gibbet', but not 'orchard_master', etc.
{
# Orc death

quest::say(
(($zonesn =~ /(g|l)faydark/) || ($zonesn eq 'crushbone')) ? plugin::random('You shall have all the Crushbone Orcs on your tail for my death!!') :
"DEBUG: $zonesn orc death!");

$handled = 1;
}
elsif ($mname =~ /^(a\_)?gnoll(\_.+|)$/i) # Everything from 'gnoll' to 'a_gnoll_flibberty_gibbet', but not 'gnollish', etc.
{
# Gnoll death

quest::say(
($zonesn =~ /^qey/i) ? plugin::random('DEBUG: Blackburrow gnoll death!!') :
"DEBUG: $zonesn (Non-Blackburrow) gnoll death!");
$handled = 1;
}
elsif ($mname =~ /^Guard/i)
{
# Guard death

my $city = plugin::cityName();

quest::say( ($city eq 'Kelethin') ? 'Kelethin guard death!' :
($city eq 'Felwithe') ? 'Felwithe guard death!' :
"DEBUG: $city guard death!" );

$handled = 1;
}
}
}

sub defaultSlay
{
my $handled = plugin::nullzero(shift);
my $mname = plugin::val('$mname');
my $zonesn = plugin::val('$zonesn');

if (!$handled)
{
if ($mname =~ /^Guard/i)
{
# Guard kills

# 25% chance for flavor text
if (int(rand(4)) == 0)
{
my $city = plugin::cityName();

quest::say(
($city eq 'Kelethin') ? 'For the protection of all Feir\'dal, there shall be no mercy for your kind.' :
($city eq 'Felwithe') ? 'Another one bites the dust.' :
"$city is a little bit safer now." );
}

$handled = 1;
}
}
}

sub defaultCombat()
{
my $combat_state = plugin::val('$combat_state');
my $npc = plugin::val('$npc');

if ($combat_state == 0)
{
$npc->Heal();
}
}
return;

# Sample code to work from
my $random_result = int(rand(100));
if(($combat_state == 1) &&($random_result<=50)){
quest::say("Death!! Death to all who oppose the Crushbone orcs!!");
}else{
quest::say("You've ruined your lands. You'll not ruin mine!");
}


2: default.pl



sub EVENT_COMBAT
{
if ($combat_state = 0)
{
$npc->Heal();
}
}

copy---default.pl to c:/peq/quest/ finishing is ok?

trevius
11-09-2012, 03:41 AM
No, that is not correct. You almost have the plugin correct, but you have extra script lines at the end that will break your plugins:

You should be able to delete this:
return;

# Sample code to work from
my $random_result = int(rand(100));
if(($combat_state == 1) &&($random_result<=50)){
quest::say("Death!! Death to all who oppose the Crushbone orcs!!");
}else{
quest::say("You've ruined your lands. You'll not ruin mine!");
}

At the end of your plugin file you posted.

Next, you would want to call that plugin from your default.pl file. You do not want to put the default.pl directly in your quests folder, you want it in quests/templates/default.pl so it will effect all NPCs that do not already have a script associated with them.

Then, in that default.pl file, you would have the following code:
sub EVENT_COMBAT {
plugin::defaultCombat();
}

That will make it call the plugin you added to restore their HPs to 100%.

As mentioned, any NPC that already has a script associated with them in your templates folder or in the quests zone folder for the zone they are in will still need to be modified to have the new plugin added to them. If they already have an EVENT_COMBAT, you would just need to add the plugin line "plugin::defaultCombat();" inside the EVENT_COMBAT. If they don't have an EVENT_COMBAT already, you would need to add the sub EVENT_COMBAT as I posted above for your default.pl file.

Since this seems to be a bit confusing to you, there is a MUCH easier way to accomplish what you are wanting to do without even having to worry about scripts at all. You can just edit your rule_values table and set " NPC:OOCRegen" to 100. This will make all NPCs regen to 100% about 6 seconds after it leaves combat.

c0ncrete
11-09-2012, 06:34 AM
yeah, i guess the OOCRegen rule would probably be easier. i keep forgetting to familiarize myself with the various rules... :|

i'm a bit confused about what i'm reading in the source about the loading of npc quest files, however. i come up with this order from reading PerlembParser::LoadScript() in zone/embparser.cpp

1) quests/default.pl
2) quests/<zone>/<npcid>.pl
3) quests/<zone>/<npcname>.pl
4) quests/templates/<npcname>.pl
5) quests/templates/<npcid>.pl
6) quests/<zone>/default.pl
7) quests/templates/default.pl

this is what i'm looking at to come to this conclusion:

int PerlembParser::LoadScript(int npcid, const char * zone, Mob* activater)
{
if(!perl)
{
return(0);
}

//we have already tried to load this quest...
if(hasQuests.count(npcid) == 1)
{
return(1);
}

string filename = "quests/", packagename = GetPkgPrefix(npcid);
//each package name is of the form qstxxxx where xxxx = npcid (since numbers alone are not valid package names)
questMode curmode = questDefault;
FILE *tmpf;
//LogFile->write(EQEMuLog::Debug, "LoadScript(%d, %s):\n", npcid, zone);
if(!npcid || !zone)
{
//Load quests/default.pl
filename += DEFAULT_QUEST_PREFIX;
filename += ".pl";
curmode = questDefault;
}
else
{
filename += zone;
filename += "/";
#ifdef QUEST_SCRIPTS_BYNAME
string bnfilename = filename;
#endif
filename += itoa(npcid);
filename += ".pl";
curmode = questByID;

#ifdef QUEST_SCRIPTS_BYNAME
//assuming name limit stays 64 chars.
char tmpname[64];
int count0 = 0;
bool filefound = false;
tmpf = fopen(filename.c_str(), "r");
if(tmpf != NULL)
{
fclose(tmpf);
filefound = true;
}
//LogFile->write(EQEMuLog::Debug, " tried '%s': %d", filename.c_str(), filefound);

tmpname[0] = 0;
//if there is no file for the NPC's ID, try for the NPC's name
if(!filefound)
{
//revert to just path
filename = bnfilename;
const NPCType *npct = database.GetNPCType(npcid);
if(npct == NULL)
{
//LogFile->write(EQEMuLog::Debug, " no npc type");
//revert and go on with life
filename += itoa(npcid);
filename += ".pl";
curmode = questByID;
}
else
{
//trace out the ` characters, turn into -
int nlen = strlen(npct->name);
//just to make sure
if(nlen < 64)
{
int r;
//this should get our NULL as well..
for(r = 0; r <= nlen; r++)
{
tmpname[r] = npct->name[r];

//watch for 00 delimiter
if(tmpname[r] == '0')
{
count0++;
//second '0'
if(count0 > 1)
{
//stop before previous 0
tmpname[r-1] = '\0';
break;
}
}
else
{
count0 = 0;
}

//rewrite ` to be more file name friendly
if(tmpname[r] == '`')
{
tmpname[r] = '-';
}

}
filename += tmpname;
filename += ".pl";
curmode = questByName;
}
else
{
//LogFile->write(EQEMuLog::Debug, " namelen too long");
//revert and go on with life, again
filename += itoa(npcid);
filename += ".pl";
curmode = questByID;
}
}
}

#ifdef QUEST_TEMPLATES_BYNAME

tmpf = fopen(filename.c_str(), "r");
if(tmpf != NULL)
{
fclose(tmpf);
filefound = true;
}


//LogFile->write(EQEMuLog::Debug, " tried '%s': %d", filename.c_str(), filefound2);

//if there is no file for the NPC's ID or name,
//try for the NPC's name in the templates directory
//only works if we have gotten the NPC's name above
if(!filefound)
{
if(tmpname[0] != 0)
{
//revert to just path
filename = "quests/";
filename += QUEST_TEMPLATES_DIRECTORY;
filename += "/";
filename += tmpname;
filename += ".pl";
curmode = questTemplate;
//LogFile->write(EQEMuLog::Debug, " template '%s'", filename.c_str(), filefound2);
}
else
{
//LogFile->write(EQEMuLog::Debug, " no template name");
filename = "quests/";
filename += QUEST_TEMPLATES_DIRECTORY;
filename += "/";
filename += itoa(npcid);
filename += ".pl";
curmode = questTemplateByID;
}
}

#endif //QUEST_TEMPLATES_BYNAME

#endif //QUEST_SCRIPTS_BYNAME

tmpf = fopen(filename.c_str(), "r");
if(tmpf != NULL)
{
fclose(tmpf);
filefound = true;
}

// If by ID, Name or Template wasn't found, load /quests/zone/default.pl
if(!filefound)
{
//Load Default Quests Per Zone quests/zonename/default.pl
filename = bnfilename;
filename += "default.pl";
curmode = questDefaultByZone;
//LogFile->write(EQEMuLog::Debug, "LoadScript(%s)", filename.c_str());
}

tmpf = fopen(filename.c_str(), "r");
if(tmpf != NULL)
{
fclose(tmpf);
filefound = true;
}

// If zone template isn't found look for it globally /quests/template/default.pl
if(!filefound)
{
//Load Default Quests Globally
//filename = bnfilename;
filename = "quests/";
filename += QUEST_TEMPLATES_DIRECTORY;
filename += "/";
filename += "default.pl";
curmode = questDefaultByZone;
//LogFile->write(EQEMuLog::Debug, "LoadScript(%s)", filename.c_str());
}
}

am i just not reading/understanding something correctly?

EDIT:
i may have just answered my own question. it's only looking for quests/default.pl if no npcid or zoneid are supplied. i haven't looked at where this is called from, but i'm guessing it's probably pretty rare for that to occur.

trevius
11-09-2012, 07:29 AM
It looks like that would only happen if there is no NPCID or zone passed to the function. I am not sure what scenario would cause that to happen, but to my knowledge using a default.pl in the quests folder directly does not work. If it worked like that, it would override any zone specific (or any other) scripts for all NPCs.

I do know it works fine from the templates folder and it loads the default.pl file from there if it doesn't find a more specific script to load first.

javewow
11-09-2012, 07:52 AM
Your methods are not running

I have tested could not operate of pl

OOCRegen is OK,

others not running!

trevius
11-09-2012, 08:55 AM
It should work, but I am guessing you made more mistakes. If you still need help with it (if OOCRegen isn't good enough for what you want), then please post the plugin and default.pl files you created for this and where you have them saved to.