PDA

View Full Version : Songs with instrument requirements


realityincarnate
03-04-2009, 09:10 PM
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

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
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.


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