Go Back   EQEmulator Home > EQEmulator Forums > Archives > Archive::Development > Archive::Quests

Archive::Quests Archive area for Quests's posts that were moved here after an inactivity period of 90 days.

Reply
 
Thread Tools Display Modes
  #1  
Old 02-17-2004, 05:22 AM
sandy
Hill Giant
 
Join Date: Oct 2002
Posts: 212
Default Need new event

hello =)
a lot of monsters have script based on their amount of hp in percent
we need a Event_HP for example ^^
thx
__________________
Sandy
Reply With Quote
  #2  
Old 02-17-2004, 12:09 PM
Monrezz's Avatar
Monrezz
Dragon
 
Join Date: Mar 2003
Location: #loc
Posts: 745
Default

Wouldn't need to be an event, would just need to add a line or 2 to parser.cpp saying npcmob->GetHP().

Take a took in parser.cpp and embparser.cpp and you'll figure it out pretty easy.

Then just use the variable you set (eg $mobhp) and use it an in if statement.

if(($mobhp >= 2000) && $text=~/Hail/i){quest::say("I have over 2k HP!");}
__________________

kRPG Profile
Reply With Quote
  #3  
Old 02-17-2004, 12:29 PM
Monrezz's Avatar
Monrezz
Dragon
 
Join Date: Mar 2003
Location: #loc
Posts: 745
Default

Done (note this is for Perl):

zone\embparser.cpp ~ Line 165:
Code:
		ExportVar(packagename.c_str(), "hp", itoa(mob->GetHP()));
		ExportVar(packagename.c_str(), "mana", itoa(mob->GetMana()));
and ~ Line 174:
Code:
		ExportVar(packagename.c_str(), "mclass", GetEQClassName(npcmob->GetClass()));
		ExportVar(packagename.c_str(), "mobhp", itoa(npcmob->GetHP()));
		ExportVar(packagename.c_str(), "mobmana", itoa(npcmob->GetMana()));
Example uses:

if($text =~ /hp/i)
{
quest::say("You have $hp hitpoints.");
}

if($text =~ /mana/i)
{
quest::say("You have $mana mana.");
}

if($text =~ /mobhp/i)
{
quest::say("I have $mobhp hitpoints.");
}

if($text =~ /mobmana/i)
{
quest::say("I have $mobmana mana.");
}

if($text =~ /mclass/i)
{
quest::say("I am a $mclass.");
}

Hope this helps.
__________________

kRPG Profile
Reply With Quote
  #4  
Old 02-17-2004, 01:20 PM
Squiffy
Sarnak
 
Join Date: Oct 2002
Posts: 78
Default

I think he's referring to Hitpoint-driven coding, not text-driven coding that retrieves a mob's hitpoints and outputs it.

IE Terris Thule encounter. Butterflies spawn at 75%, AE 15 buff dispell at 50%, 4 Gargoyles at 25%.

I'm sure there's workarounds to get the same effect done, but a hitpoint-driven event would be useful, as well. Don't know the Perl quest system, so this syntax may be completely wrong. Just giving a rough example.

ie
Code:
Event_HP (75) {
  quest::emote("Terris Thule calls forth nightmarish wraiths");
  for (x = 0, x < 21, x++) {
    quest::spawn(a_nightmare_wraith, race, etc, etc);
  }
}

Event_HP (50) {
  quest:cast(WhateverTheAEDebuffSpellNumberIs);
}

Event_HP (25) {
  for (x = 0, x < 4, x++) {
    quest::spawn(a_gargoyle_thinger, etc);
  }
}
Reply With Quote
  #5  
Old 02-17-2004, 01:25 PM
Monrezz's Avatar
Monrezz
Dragon
 
Join Date: Mar 2003
Location: #loc
Posts: 745
Default

Could be done using what was posted above:

$75 = $mobhp*0.75
$50 = $mobhp*0.5
$25 = $mobhp*0.25

if($mobhp == $75){quest::spawn()}
if($mobhp == $50){quest::spawn()}
if($mobhp == $25){quest::spawn()}

Not perfect, but it could be done with a little effort.
__________________

kRPG Profile
Reply With Quote
  #6  
Old 02-17-2004, 01:30 PM
Squiffy
Sarnak
 
Join Date: Oct 2002
Posts: 78
Default

Yes, but what triggers these events to fire? Does the code just continuously loop every millisecond until one of the ifs is met? If so, that's rather inefficient.

Don't know if it makes a huge difference or not, I'm just used to making my code as efficient as possible, and I know if this were a program I was creating, I'd have it as an event that is called once, not an infinitely looping event with if statements.

lol and I just realized I mixed in C and VB in some mutated bastardized version of code there
Reply With Quote
  #7  
Old 02-19-2004, 12:45 PM
Daeath
Sarnak
 
Join Date: Feb 2004
Posts: 55
Default

Quote:
Originally Posted by Squiffy
Yes, but what triggers these events to fire? Does the code just continuously loop every millisecond until one of the ifs is met? If so, that's rather inefficient.
Well, has anyone had success with this script yet? Does it create alot of server lag? What do you suggest Squiffy? I'm curious since I'm doing a major overhaul of the PoNightmare and TT could really use this event...
Reply With Quote
  #8  
Old 02-19-2004, 05:24 PM
m0oni9
Hill Giant
 
Join Date: Dec 2003
Posts: 166
Default

I have a quick and dirty interim way to implement this.

In Mob::CreateHPPacket(), mob.cpp, about line 688:
Code:
   else
   {
      if(IsNPC() && IsEngaged())
        parse->Event(EVENT_HP, GetNPCTypeID(), NULL, CastToNPC(), CastToMob());
      ds->cur_hp=IsNPC()?(sint32)GetHPRatio():cur_hp;
      ds->max_hp=100;
   }
In PerlembParser::Event(), embparser.cpp, about line 184:
Code:
                        break;
                }
                case EVENT_HP: {
                        SendCommands(packagename.c_str(), "EVENT_HP", npcid,
                                npcmob, mob);
                }
                default: {
event_codes.h, add:
Code:
#define EVENT_HP  9
(imho would look better with enums in here)

You should now be able to make an EVENT_HP sub in your script. You can use the code Monrezz supplied to get access to mob HP, and possibly create another variable (ie: mobHPpercent). The problem with this implementation is that it is (possibly) invoked every time HP updates happen, which is very frequently -- however, I'll note that it didn't affect my load noticeably. I really can't see this being implemented in a way other than using a timer, and calling EVENT_HP sub on engaged mobs, so hopefully this won't be too far off.
Reply With Quote
  #9  
Old 02-20-2004, 12:39 AM
Scorpious2k's Avatar
Scorpious2k
Demi-God
 
Join Date: Mar 2003
Location: USA
Posts: 1,067
Default

The only problem I see with this (not having checked the code) is: how many times per second will the event be triggered? Doesn't this have the potential to bring a server to its knees?
__________________
Maybe I should try making one of these servers...
Reply With Quote
  #10  
Old 02-20-2004, 06:49 AM
Monrezz's Avatar
Monrezz
Dragon
 
Join Date: Mar 2003
Location: #loc
Posts: 745
Default

He said it is called for everytime HP updates are called for, so it depends how often they're called for I guess :P
__________________

kRPG Profile
Reply With Quote
  #11  
Old 02-20-2004, 08:43 AM
m0oni9
Hill Giant
 
Join Date: Dec 2003
Posts: 166
Default

Quote:
The only problem I see with this (not having checked the code) is: how many times per second will the event be triggered? Doesn't this have the potential to bring a server to its knees?
Yes, it has the potential, as I noted. This isn't the final implementation serverside, but a quick add for anyone that wants to play around with this in their perl scripts. The way to go about using it would remain as creating an EVENT_HP sub, and accessing a, for example, mobhppercent variable.

I imagine it will be written this way: 1) keep a global list of mobs with aggro, 2) start a timer of 20 seconds or so, 3) run EVENT_HP for each mob in list. But that won't change how perl scripts use it, so it won't matter to script writers. Of course there may just be a timer inserted into how it currently functions. That could work too.
Reply With Quote
  #12  
Old 02-21-2004, 08:58 AM
smogo
Discordant
 
Join Date: Jan 2004
Location: 47
Posts: 339
Default

the events described above are Mob AI events. For performance reasons, one could doubt it is safe to put them in perl scripts, especially if it is to be called every X ms.

However, it is insteresting to get triggers that run some script depending on HP. i guess the best would be to trigger a few events, like 'half-life', or 'low-life' at 10 % hp, maybe with some hysterisys or one-shot mechanisms.

The drawback is that we get these events triggered for every Mob ; so far, i don't think the code checks for what event is effectively used by the mob's script. One solution would be to flag this when the script is read from the file and compiled, one other to mark Mobs in the DB if they require additional triggers / variables (ala qglobal).
Reply With Quote
  #13  
Old 02-21-2004, 05:01 PM
Lurker_005
Demi-God
 
Join Date: Jan 2002
Location: Tourist town USA
Posts: 1,671
Default

In a EVENT_ATTACK start a timer that fires every 5 sec or so. Then in EVENT_TIMER place teh code to check the HP. Perhaps work something out to turn off the timer also. That way if the attack failed the timer will eventually go away.
__________________
Please read the forum rules and look at reacent messages before posting.
Reply With Quote
  #14  
Old 02-21-2004, 08:20 PM
m0oni9
Hill Giant
 
Join Date: Dec 2003
Posts: 166
Default

Every mob does not send an HP update packet every second. It really starts when their HP < 100% (or when first engaged, have to double-check).

Also, a perl script isn't really "run" in the sense that it keeps reading these scripts off of the disk. They are compiled when loaded, and remain in memory for the duration of the package, afaik. This isn't taking into account exported variables, of course.

I hadn't thought of Lurker's idea. If the script timers are working well, that doesn't sound bad at all. We could export a variable that would say whether the mob was engaged or not, and when EVENT_TIMER was triggered, it could disable based on that.

On a side note, one of the things I don't like is the amount of variables exported. I have XS code that will work in terms of creating functions that can be called from perl, and receive a return value. You still would need to have a module.pm file somewhere for it to be able to deal with it, however. But this would eliminate some overhead.
Reply With Quote
  #15  
Old 02-22-2004, 01:45 AM
Scorpious2k's Avatar
Scorpious2k
Demi-God
 
Join Date: Mar 2003
Location: USA
Posts: 1,067
Default

Quote:
Originally Posted by m0oni9
I hadn't thought of Lurker's idea. If the script timers are working well, that doesn't sound bad at all. We could export a variable that would say whether the mob was engaged or not, and when EVENT_TIMER was triggered, it could disable based on that.
Or an EVENT_HEALTH (as opposed to EVENT_HP so you could report mana etc too) as you suggested, but incorporate Lurker's idea of a timer. In other words, once the event is triggered, start a timer that won't allow it to be triggered again for a few seconds.

Wouldn't that satisfy both the need for the event and the concern for cpu/bandwidth conservation?

Also, although this has been discussed from a perl quest point of view, I would like to note that both formats are supported and any changes should work in both.
__________________
Maybe I should try making one of these servers...
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 04:50 PM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3