Jump to content

EventAI extensions via scripts library


Recommended Posts

Posted

Currently EventAI cannot be used together with scripts. It leads to a lot of code in scripts that can be easily implemented via EventAI.

So that's why the following idea is proposed:

1. Add new EVENT_T_CUSTOM that will delegate checking event conditions to scripts

2. Add new ACTION_T_CUSTOM that will delegate event action to scripts

3. Add new TargetByType constant to delegate target selection to scripts

This allows to implement several custom conditions/actions via scripts leaving everything else to EventAI.

Here is patch for mangos to support such customEAI handler:

http://github.com/seirge/sd2fx/blob/master/patches/customEAI.patch

Changes required for scriptdev2 are here: http://github.com/seirge/sd2fx/commit/e0e01abeea1d80017b32ba2a429d132f61990dc8

You can also find examples of converted AIs in that repository.

Posted

I worry about mixing eventAI and scriting library functionality.

In past and continue we attempt move functions from scripting calls to AI call in scripting API

Suggection chnages adding reversed way (from specialized AI to generic scripting calls at scriopt level (in different from AI level). This can create very unclear code.

For me more natural way just write scriot in C++ if EventAI functionality not let do it.

This will be inproper use EventAI for wrong cases when creating script in Event AI form required redundent states and events data. Event AI DB engine is similar in any case to any scripting language engine (with precomiling) and we buy easy way write simple scripts for more slow exacute. But simple scripts this is small different in speed we use mosltly same commands just in another form. For not simple cases attempt put extanded functionality to EventAi will in result real slow work related EventAI in different similar C++ script.

Maybe walk in another way? Instead creating diff C++ hooks just look what new events/commands possible add to EventAi is some near to simple scripts just limited by this absent features.

Posted

Current code for almost all bosses are not clean (or beautiful). For example, it has great number of copy'n'paste for repeating simple casts (that can be easily done via EAI).

As I see there are only two way to solve such issues (for example, http://github.com/seirge/sd2fx/blob/38b615fe3273f17829bef5b37b27b4190df89745/scripts/northrend/naxxramas/boss_patchwerk.cpp )

1. reimplement events subsystem in scripts (as in tc2 is done)

2. use existing core EventAI subsystem (as proposed).

Other idea is to left as it is. But absence of any strict principles in ScriptedAI leads to very unclean and large code.

The problem in extending EventAI in core is in fact that real custom actions are required sometimes (choose a target from top3 except top1 if other exist with most HP for example).

Implement the whole boss AI as ScriptedAI only because one target of one spell is custom is rather bad idea.

Posted

Personally, I like it and hate it at the same time.

On the negative side: this does mix the two systems in a way that makes deciphering already-hard-to-understand EventAI scripts even harder (you must have knowledge of both systems and C++, and search through database tables and script files)

On the brighter side: it allows for very powerful generic programming; you can make very diverse scripts in EventAI and have them share only one or more complicated functions coded in C++. For example, say you have a bunch of very different mobs in an instance, but on death they need to check if the other mobs are alive and an instance variable is set and act accordingly, this makes it possible without bloating compile time and space with more scripts and C++ code. It also allows for better bridging between EventAI and C++ coders in regards to scripting; EAI coders can request functions from C++ coders, C++ coders can deliver functions, etc.

Whether or not you guys like it, all I can say is I would probably use it.

Also, just saw 2 things:

1st: your new event is never actually called in the EventAI code. I assume it should be called on UpdateAI() for the creature, so this:

                //Events that are updated every EVENT_UPDATE_TIME
               switch ((*i).Event.event_type)
               {
                   case EVENT_T_TIMER_OOC:
                       ProcessEvent(*i);
                       break;
                   case EVENT_T_TIMER:
                   case EVENT_T_MANA:
                   case EVENT_T_HP:
                   case EVENT_T_TARGET_HP:
                   case EVENT_T_TARGET_CASTING:
                   case EVENT_T_FRIENDLY_HP:
                       if (Combat)
                           ProcessEvent(*i);
                       break;
                   case EVENT_T_RANGE:
                       if (Combat)
                       {
                           if (m_creature->getVictim() && m_creature->IsInMap(m_creature->getVictim()))
                               if (m_creature->IsInRange(m_creature->getVictim(), (float)(*i).Event.range.minDist, (float)(*i).Event.range.maxDist))
                                   ProcessEvent(*i);
                       }
                       break;
               }

Should be this:

                //Events that are updated every EVENT_UPDATE_TIME
               switch ((*i).Event.event_type)
               {
                   case EVENT_T_TIMER_OOC:
                  [b] case EVENT_T_CUSTOM[/b]
                       ProcessEvent(*i);
                       break;
                   case EVENT_T_TIMER:
                   case EVENT_T_MANA:
                   case EVENT_T_HP:
                   case EVENT_T_TARGET_HP:
                   case EVENT_T_TARGET_CASTING:
                   case EVENT_T_FRIENDLY_HP:
                       if (Combat)
                           ProcessEvent(*i);
                       break;
                   case EVENT_T_RANGE:
                       if (Combat)
                       {
                           if (m_creature->getVictim() && m_creature->IsInMap(m_creature->getVictim()))
                               if (m_creature->IsInRange(m_creature->getVictim(), (float)(*i).Event.range.minDist, (float)(*i).Event.range.maxDist))
                                   ProcessEvent(*i);
                       }
                       break;
               }

2nd: you forget the break in the coding for your custom event, it should be:

case EVENT_T_CUSTOM:
{
if (ExtendedCreatureEAI != NULL)
{
if (!ExtendedCreatureEAI->CheckEvent(event))
return false;
}
else
{
sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u has Custom Event Type, but ExtendedCreatureEAI is NULL", m_creature->GetEntry(), pHolder.Event.event_id);
}
[b]break;[/b]
}

My apologies if I am wrong on either of these.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use