EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Development::Server Code Submissions (https://www.eqemulator.org/forums/forumdisplay.php?f=669)
-   -   Songs with instrument requirements (https://www.eqemulator.org/forums/showthread.php?t=27610)

realityincarnate 03-04-2009 09:10 PM

Songs with instrument requirements
 
I'm not sure all that many bards will thank me for it, but this code should enable the check for instruments on bard songs that require a specific instrument type. I did some local testing and it works with all the instruments and weapons with instrument effects that I tried.

I added the instrument messages into stringIDs.h on my end, but I'm not sure whether it's really worth doing. It makes the code more readable, but since I can't imagine the strings would ever be used again I don't know that they really need to be #defined.

Here's a diff against revision 372
Code:

Index: spells.cpp
===================================================================
--- spells.cpp        (revision 372)
+++ spells.cpp        (working copy)
@@ -862,8 +862,8 @@
       
       
        // Check for consumables and Reagent focus items
-        // first check for component reduction... we assume bard spells never have components
-        if(!bard_song_mode && IsClient()) {
+        // first check for component reduction
+        if(IsClient()) {
                int reg_focus = CastToClient()->GetFocusEffect(focusReagentCost,spell_id);
                if(MakeRandomInt(0, 100) <= reg_focus) {
                        mlog(SPELLS__CASTING, "Spell %d: Reagent focus item prevented reagent consumption (%d chance)", spell_id, reg_focus);
@@ -878,47 +878,104 @@
       
                                if (component == -1)
                                        continue;
-                                if(c->GetInv().HasItem(component, component_count, invWhereWorn|invWherePersonal) == -1) // item not found
-                                {
-                                        c->Message_StringID(13, MISSING_SPELL_COMP);
-       
-                                        const Item_Struct *item = database.GetItem(component);
-                                        if(item) {
-                                                c->Message_StringID(13, MISSING_SPELL_COMP_ITEM, item->Name);
-                                                mlog(SPELLS__CASTING_ERR, "Spell %d: Canceled. Missing required reagent %s (%d)", spell_id, component, item->Name);
+                               
+                                // bard components are requirements for a certain instrument type, not a specific item
+                                if(bard_song_mode) {
+                                        bool HasInstrument = true;
+                                       
+                                        switch (component) {
+                                                // percussion songs (13000 = hand drum)
+                                                case 13000:
+                                                        if(itembonuses.percussionMod == 0) {                        // check for the appropriate instrument type
+                                                                HasInstrument = false;
+                                                                c->Message_StringID(13, SONG_NEEDS_DRUM);        // send an error message if missing
+                                                        }
+                                                        break;
+                                                                                               
+                                                // wind songs (13001 = wooden flute)
+                                                case 13001:
+                                                        if(itembonuses.windMod == 0) {
+                                                                HasInstrument = false;
+                                                                c->Message_StringID(13, SONG_NEEDS_WIND);
+                                                        }
+                                                        break;
+                                               
+                                                // string songs (13011 = lute)
+                                                case 13011:
+                                                        if(itembonuses.stringedMod == 0) {
+                                                                HasInstrument = false;
+                                                                c->Message_StringID(13, SONG_NEEDS_STRINGS);
+                                                        }
+                                                        break;
+                                               
+                                                // brass songs (13012 = horn)
+                                                case 13012:
+                                                        if(itembonuses.brassMod == 0) {
+                                                                HasInstrument = false;
+                                                                c->Message_StringID(13, SONG_NEEDS_BRASS);
+                                                        }
+                                                        break;
+                                               
+                                                default:        // some non-instrument component.  Let it go, but record it in the log
+                                                        mlog(SPELLS__CASTING_ERR, "Something odd happened: Song %d required component %s", spell_id, component);
                                        }
-                                        else {
-                                                char TempItemName[64];
-                                                strcpy((char*)&TempItemName, "UNKNOWN");
-                                                mlog(SPELLS__CASTING_ERR, "Spell %d: Canceled. Missing required reagent %s (%d)", spell_id, component, TempItemName);
+
+                                        if(!HasInstrument) {        // if the instrument is missing, log it and interrupt the song
+                                                mlog(SPELLS__CASTING_ERR, "Song %d: Canceled. Missing required instrument %s", spell_id, component);
+                                                if(c->GetGM())
+                                                        c->Message(0, "Your GM status allows you to finish casting even though you're missing a required instrument.");
+                                                else {
+                                                        InterruptSpell();
+                                                        return;
+                                                }
                                        }
+                                }        // end bard component section
+
+
+                                // handle the components for traditional casters
+                                else {
+                                        if(c->GetInv().HasItem(component, component_count, invWhereWorn|invWherePersonal) == -1) // item not found
+                                        {
+                                                c->Message_StringID(13, MISSING_SPELL_COMP);
+       
+                                                const Item_Struct *item = database.GetItem(component);
+                                                if(item) {
+                                                        c->Message_StringID(13, MISSING_SPELL_COMP_ITEM, item->Name);
+                                                        mlog(SPELLS__CASTING_ERR, "Spell %d: Canceled. Missing required reagent %s (%d)", spell_id, component, item->Name);
+                                                }
+                                                else {
+                                                        char TempItemName[64];
+                                                        strcpy((char*)&TempItemName, "UNKNOWN");
+                                                        mlog(SPELLS__CASTING_ERR, "Spell %d: Canceled. Missing required reagent %s (%d)", spell_id, component, TempItemName);
+                                                }
                                       
-                                        if(c->GetGM())
-                                                c->Message(0, "Your GM status allows you to finish casting even though you're missing required components.");
-                                        else {
-                                                InterruptSpell();
-                                                return;
+                                                if(c->GetGM())
+                                                        c->Message(0, "Your GM status allows you to finish casting even though you're missing required components.");
+                                                else {
+                                                        InterruptSpell();
+                                                        return;
+                                                }
                                        }
-                                }
-                                else
-                                {
-                                        mlog(SPELLS__CASTING_ERR, "Spell %d: Consuming %d of spell component item id %d", spell_id, component, component_count);
-                                        // Components found, Deleteing
-                                        // now we go looking for and deleting the items one by one
-                                        for(int s = 0; s < component_count; s++)
+                                        else
                                        {
-                                                inv_slot_id = c->GetInv().HasItem(component, 1, invWhereWorn|invWherePersonal);
-                                                if(inv_slot_id != -1)
+                                                mlog(SPELLS__CASTING_ERR, "Spell %d: Consuming %d of spell component item id %d", spell_id, component, component_count);
+                                                // Components found, Deleteing
+                                                // now we go looking for and deleting the items one by one
+                                                for(int s = 0; s < component_count; s++)
                                                {
-                                                        c->DeleteItemInInventory(inv_slot_id, 1, true);
+                                                        inv_slot_id = c->GetInv().HasItem(component, 1, invWhereWorn|invWherePersonal);
+                                                        if(inv_slot_id != -1)
+                                                        {
+                                                                c->DeleteItemInInventory(inv_slot_id, 1, true);
+                                                        }
+                                                        else
+                                                        {        // some kind of error in the code if this happens
+                                                                c->Message(13, "ERROR: reagent item disappeared while processing?");
+                                                        }
                                                }
-                                                else
-                                                {        // some kind of error in the code if this happens
-                                                        c->Message(13, "ERROR: reagent item disappeared while processing?");
-                                                }
                                        }
-                                }
-                    } // end reagent loop
+                                } // end bard/not bard ifs
+                        } // end reagent loop
                } // end `focus did not help us`
        } // end IsClient() for reagents
       
Index: StringIDs.h
===================================================================
--- StringIDs.h        (revision 372)
+++ StringIDs.h        (working copy)
@@ -186,5 +186,10 @@
 #define MORE_SKILLED_THAN_I 12931 //%1 tells you, 'You are more skilled than I!  What could I possibly teach you?'
 #define CANNOT_BIND 105  // "You cannot form an affinity with this area.  Try a city."
 #define DIVINE_INTERVENTION 1029 // %1 has been rescued by divine intervention!
 #define GAIN_RAIDEXP 5085       
+#define SONG_NEEDS_DRUM 405        // You need to play a percussion instrument for this song
+#define SONG_NEEDS_WIND 406        // You need to play a wind instrument for this song
+#define SONG_NEEDS_STRINGS 407        // You need to play a stringed instrument for this song
+#define SONG_NEEDS_BRASS 408        // You need to play a brass instrument for this song
 #endif


cavedude 03-06-2009 01:47 PM

This looks good, I'll have it in SVN the next time I commit.

realityincarnate 03-08-2009 12:45 PM

A minor adjustment
 
It looks like the first instrument code affected a couple of songs that aren't supposed to have requirements. The proper songs seem to have an instrument listed as both a component and a focus item. The following change fixes it for all the songs that I know of.

Code:

Index: zone/spells.cpp
===================================================================
--- zone/spells.cpp        (revision 376)
+++ zone/spells.cpp        (working copy)
@@ -882,8 +882,12 @@
                                // bard components are requirements for a certain instrument type, not a specific item
                                if(bard_song_mode) {
                                        bool HasInstrument = true;
-                                       
-                                        switch (component) {
+                                        int InstComponent = spells[spell_id].NoexpendReagent[0];
+                                                                                                                       
+                                        switch (InstComponent) {
+                                                case -1:
+                                                        continue;                // no instrument required, go to next component
+                                               
                                                // percussion songs (13000 = hand drum)
                                                case 13000:
                                                        if(itembonuses.percussionMod == 0) {                        // check for the appropriate instrument type



All times are GMT -4. The time now is 05:20 PM.

Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.