cmangos / issues

This repository is used as a centralized point for all issues regarding CMaNGOS.
179 stars 47 forks source link

Need new event EVENT_T_ENERGY. #511

Closed ghost closed 9 years ago

ghost commented 9 years ago

http://www.wowhead.com/npc=57159 example. http://www.wowhead.com/spell=107852, gives him 34 energy. http://www.wowhead.com/spell=107872, Has 100 energy cast Twilight Rage and resets the amount of energy. Can be done through ACTION_T_SET_UNIT_FIELD. inline bool IsTimerBasedEvent(EventAI_Type type)

{
    switch (type)
    {
        case EVENT_T_TIMER_IN_COMBAT:
        case EVENT_T_TIMER_OOC:
        case EVENT_T_TIMER_GENERIC:
        case EVENT_T_MANA:
        case EVENT_T_ENERGY:
        case EVENT_T_HP:
        case EVENT_T_TARGET_HP:
        case EVENT_T_TARGET_CASTING:
        case EVENT_T_FRIENDLY_HP:
        case EVENT_T_AURA:
        case EVENT_T_TARGET_AURA:
        case EVENT_T_MISSING_AURA:
        case EVENT_T_TARGET_MISSING_AURA:
        case EVENT_T_RANGE:
            return true;
        default:
            return false;
    }
}
case EVENT_T_ENERGY:
        {
           if (!m_creature->isInCombat() || !m_creature->GetMaxPower(POWER_ENERGY))
                return false;

            uint32 perc = (m_creature->GetPower(POWER_ENERGY) * 100) / m_creature->GetMaxPower(POWER_ENERGY);

            if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin)
                return false;

            LOG_PROCESS_EVENT;
            // Repeat Timers
            pHolder.UpdateRepeatTimer(m_creature, event.percent_range.repeatMin, event.percent_range.repeatMax);
            break;
        }
                case EVENT_T_HP:
                case EVENT_T_MANA:
                case EVENT_T_ENERGY:
                case EVENT_T_TARGET_HP:
                case EVENT_T_TARGET_MANA:
                    if (temp.percent_range.percentMax > 100)
                        sLog.outErrorEventAI("Creature %u are using percentage event(%u) with param2 (MinPercent) > 100. Event will never trigger! ", temp.creature_id, i);

                    if (temp.percent_range.percentMax <= temp.percent_range.percentMin)
                        sLog.outErrorEventAI("Creature %u are using percentage event(%u) with param1 <= param2 (MaxPercent <= MinPercent). Event will never trigger! ", temp.creature_id, i);

                    if (temp.event_flags & EFLAG_REPEATABLE && !temp.percent_range.repeatMin && !temp.percent_range.repeatMax)
                    {
                        sLog.outErrorEventAI("Creature %u has param3 and param4=0 (RepeatMin/RepeatMax) but cannot be repeatable without timers. Removing EFLAG_REPEATABLE for event %u.", temp.creature_id, i);
                        temp.event_flags &= ~EFLAG_REPEATABLE;
                    }
                    break;
void CreatureEventAI::UpdateAI(const uint32 diff)
{
    // Check if we are in combat (also updates calls threat update code)
    bool Combat = m_creature->SelectHostileTarget() && m_creature->getVictim();

    // Events are only updated once every EVENT_UPDATE_TIME ms to prevent lag with large amount of events
    if (m_EventUpdateTime < diff)
    {
        m_EventDiff += diff;

        // Check for time based events
        for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
        {
            // Decrement Timers
            if ((*i).Time)
            {
                if ((*i).Time > m_EventDiff)
                {
                    // Do not decrement timers if event cannot trigger in this phase
                    if (!((*i).Event.event_inverse_phase_mask & (1 << m_Phase)))
                        (*i).Time -= m_EventDiff;

                    // Skip processing of events that have time remaining
                    continue;
                }
                else (*i).Time = 0;
            }

            // Events that are updated every EVENT_UPDATE_TIME
            switch ((*i).Event.event_type)
            {
                case EVENT_T_TIMER_OOC:
                case EVENT_T_TIMER_GENERIC:
                    ProcessEvent(*i);
                    break;
                case EVENT_T_TIMER_IN_COMBAT:
                case EVENT_T_MANA:
                case EVENT_T_ENERGY:
                case EVENT_T_HP:
                case EVENT_T_TARGET_HP:
                case EVENT_T_TARGET_CASTING:
                case EVENT_T_FRIENDLY_HP:
                case EVENT_T_AURA:
                case EVENT_T_TARGET_AURA:
                case EVENT_T_MISSING_AURA:
                case EVENT_T_TARGET_MISSING_AURA:
                    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;
            }
        }

        m_EventDiff = 0;
        m_EventUpdateTime = EVENT_UPDATE_TIME;
    }
    else
    {
        m_EventDiff += diff;
        m_EventUpdateTime -= diff;
    }

    // Melee Auto-Attack (recheck m_creature->getVictim in case of combat state was changed while processing events)
    if (Combat && m_MeleeEnabled && m_creature->getVictim())
        DoMeleeAttackIfReady();
}
xfurry commented 9 years ago

Interesting. It can be a good addition to the core.

Schmoozerd commented 9 years ago

yes, sounds reasonable. And no trouble at all to add it.

I will do so when i have some time for it, if you want things to be much faster, best create a patch (and do not forget to also add the new event-type to the doc/eventAi.txt file

xfurry commented 9 years ago

Offtopic: why is always github displaying a different author for you?

ghost commented 9 years ago

The man spent his time and did it! I thank him for it) That shows his authorship - this is normal! But I have another question - why in Wotlk, but not in Cataclysm? By Wotlk it has nothing to do practically! Example some of the Cataclysm!

xfurry commented 9 years ago

why in Wotlk, but not in Cataclysm?

Will be backported soonish. I have to clarify how to proceed with the workflow on cata and wod first.

ghost commented 9 years ago

Wow, I missed something and Mangos appeared WOD?

VladimirMangos commented 9 years ago

https://github.com/cmangos/cmangos-wod

ghost commented 9 years ago

Not bad! Thanks for the info, Vladimir! Неплохо! Спасибо за информацию, Владимир!

Schmoozerd commented 9 years ago

@xfurry - for some reason you linked the authorship to

"Ulduar noreply@github.com"

And obviously the user ileopard.. has linked the email noreply... to his profile, hence he is linked via github.

To avoid this i suggest to use commit --author="Ulduar ulduar@cmangos.net" as dummy email (or the email @Ulduar suggests!) with the next commit. With the first @Ulduar can link the dummy-email to his github profile, in the second you can expect him to be already linked :)

Edit: Thanks for pushing this change so quickly!

ghost commented 9 years ago

Yes inappropriately put my authorship here! I just did a copy-paste. Took EVENT_T_MANA copied replaced at MANA ENERGY and all! So that my authorship immediately put - this is ridiculous! I am not the author!

Schmoozerd commented 9 years ago

still you did it :) It did not exist before, you did work, it exists now. Hence you are the author. It is not always about complexity or difficulty. Also you must keep in mind the work to research the need for this feature. Or actually the work to chose that adding a new event-type is better than expanding other event-type (ie EVENT_T_POWER_PERCENT replacing EVENT_T_MANA_PERCENT)

ghost commented 9 years ago

EVENT_T_POWER_PERCENT - good solution, but not too successfully. Can be difficult. We must somehow force the kernel to think that Mana - Mana is, not rage, and the energy is energy, and not Runic Power.

xfurry commented 9 years ago

Or actually the work to chose that adding a new event-type is better than expanding other event-type

Technically we can change this. We remove the recently added commit and change EVENT_T_MANA to EVENT_T_POWER_PERCENT and use the m_creature->GetPowerType() in order to define which power to use.

I think this can be a good idea. :+1:

Schmoozerd commented 9 years ago

percent-min, percent-max, repeat-min, repeat-max No space left for type :)

xfurry commented 9 years ago

Actually I mean this one:

diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp
index 2832f86..d25d8e9 100644
--- a/src/game/CreatureEventAI.cpp
+++ b/src/game/CreatureEventAI.cpp
@@ -164,7 +164,7 @@ inline bool IsTimerBasedEvent(EventAI_Type type)
         case EVENT_T_TIMER_IN_COMBAT:
         case EVENT_T_TIMER_OOC:
         case EVENT_T_TIMER_GENERIC:
-        case EVENT_T_MANA:
+        case EVENT_T_POWER_PERCENT:
         case EVENT_T_HP:
         case EVENT_T_TARGET_HP:
         case EVENT_T_TARGET_CASTING:
@@ -173,6 +173,7 @@ inline bool IsTimerBasedEvent(EventAI_Type type)
         case EVENT_T_TARGET_AURA:
         case EVENT_T_MISSING_AURA:
         case EVENT_T_TARGET_MISSING_AURA:
+        case EVENT_T_TARGET_POWER_PERCENT:
         case EVENT_T_RANGE:
             return true;
         default:
@@ -237,12 +238,12 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
             pHolder.UpdateRepeatTimer(m_creature, event.percent_range.repeatMin, event.percent_range.repeatMax);
             break;
         }
-        case EVENT_T_MANA:
+        case EVENT_T_POWER_PERCENT:
         {
-            if (!m_creature->isInCombat() || !m_creature->GetMaxPower(POWER_MANA))
+            if (!m_creature->isInCombat() || !m_creature->GetMaxPower(m_creature->GetPowerType()))
                 return false;

-            uint32 perc = (m_creature->GetPower(POWER_MANA) * 100) / m_creature->GetMaxPower(POWER_MANA);
+            uint32 perc = (m_creature->GetPower(m_creature->GetPowerType()) * 100) / m_creature->GetMaxPower(m_creature->GetPowerType());

             if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin)
                 return false;
@@ -374,12 +375,12 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
             pHolder.UpdateRepeatTimer(m_creature, event.summoned.repeatMin, event.summoned.repeatMax);
             break;
         }
-        case EVENT_T_TARGET_MANA:
+        case EVENT_T_TARGET_POWER_PERCENT:
         {
-            if (!m_creature->isInCombat() || !m_creature->getVictim() || !m_creature->getVictim()->GetMaxPower(POWER_MANA))
+            if (!m_creature->isInCombat() || !m_creature->getVictim() || !m_creature->getVictim()->GetMaxPower(m_creature->getVictim()->GetPowerType()))
                 return false;

-            uint32 perc = (m_creature->getVictim()->GetPower(POWER_MANA) * 100) / m_creature->getVictim()->GetMaxPower(POWER_MANA);
+            uint32 perc = (m_creature->getVictim()->GetPower(m_creature->getVictim()->GetPowerType()) * 100) / m_creature->getVictim()->GetMaxPower(m_creature->getVictim()->GetPowerType());

             if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin)
                 return false;
diff --git a/src/game/CreatureEventAI.h b/src/game/CreatureEventAI.h
index accc8fd..4652e51 100644
--- a/src/game/CreatureEventAI.h
+++ b/src/game/CreatureEventAI.h
@@ -36,7 +36,7 @@ enum EventAI_Type
     EVENT_T_TIMER_IN_COMBAT         = 0,                    // InitialMin, InitialMax, RepeatMin, RepeatMax
     EVENT_T_TIMER_OOC               = 1,                    // InitialMin, InitialMax, RepeatMin, RepeatMax
     EVENT_T_HP                      = 2,                    // HPMax%, HPMin%, RepeatMin, RepeatMax
-    EVENT_T_MANA                    = 3,                    // ManaMax%,ManaMin% RepeatMin, RepeatMax
+    EVENT_T_POWER_PERCENT           = 3,                    // ManaMax%,ManaMin% RepeatMin, RepeatMax
     EVENT_T_AGGRO                   = 4,                    // NONE
     EVENT_T_KILL                    = 5,                    // RepeatMin, RepeatMax
     EVENT_T_DEATH                   = 6,                    // NONE
@@ -51,7 +51,7 @@ enum EventAI_Type
     EVENT_T_FRIENDLY_IS_CC          = 15,                   // DispelType, Radius, RepeatMin, RepeatMax
     EVENT_T_FRIENDLY_MISSING_BUFF   = 16,                   // SpellId, Radius, RepeatMin, RepeatMax
     EVENT_T_SUMMONED_UNIT           = 17,                   // CreatureId, RepeatMin, RepeatMax
-    EVENT_T_TARGET_MANA             = 18,                   // ManaMax%, ManaMin%, RepeatMin, RepeatMax
+    EVENT_T_TARGET_POWER_PERCENT    = 18,                   // ManaMax%, ManaMin%, RepeatMin, RepeatMax
     EVENT_T_QUEST_ACCEPT            = 19,                   // QuestID
     EVENT_T_QUEST_COMPLETE          = 20,                   //
     EVENT_T_REACHED_HOME            = 21,                   // NONE
@@ -448,9 +448,9 @@ struct CreatureEventAI_Event
             uint32 repeatMax;
         } timer;
         // EVENT_T_HP                                       = 2
-        // EVENT_T_MANA                                     = 3
+        // EVENT_T_POWER_PERCENT                            = 3
         // EVENT_T_TARGET_HP                                = 12
-        // EVENT_T_TARGET_MANA                              = 18
+        // EVENT_T_TARGET_POWER_PERCENT                     = 18
         struct
         {
             uint32 percentMax;
diff --git a/src/game/CreatureEventAIMgr.cpp b/src/game/CreatureEventAIMgr.cpp
index 4cdb73e..9d66ef7 100644
--- a/src/game/CreatureEventAIMgr.cpp
+++ b/src/game/CreatureEventAIMgr.cpp
@@ -318,9 +318,9 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
                         sLog.outErrorEventAI("Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
                     break;
                 case EVENT_T_HP:
-                case EVENT_T_MANA:
+                case EVENT_T_POWER_PERCENT:
                 case EVENT_T_TARGET_HP:
-                case EVENT_T_TARGET_MANA:
+                case EVENT_T_TARGET_POWER_PERCENT:
                     if (temp.percent_range.percentMax > 100)
                         sLog.outErrorEventAI("Creature %u are using percentage event(%u) with param2 (MinPercent) > 100. Event will never trigger! ", temp.creature_id, i);