|  |  | 
 
  |  |  |  |  
  |  |  |  |  
  |  |  |  |  
  |  |  |  |  
  |  | 
	
	
		
	
	
 
  |  |  |  |  
	| 
			
			 
			
				03-04-2009, 09:10 PM
			
			
			
		 |  
	| 
		
			
			| Developer |  | 
					Join Date: Dec 2007 
						Posts: 122
					      |  |  
	| 
				 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
			
			
			
			
				  |  
 
  |  |  |  |  
	
		
	
	
	| 
			
			 
			
				03-06-2009, 01:47 PM
			
			
			
		 |  
	| 
		
			|  | The PEQ Dude |  | 
					Join Date: Apr 2003 Location: - 
						Posts: 1,988
					      |  |  
	| 
 This looks good, I'll have it in SVN the next time I commit. |  
	
		
	
	
	| 
			
			 
			
				03-08-2009, 12:45 PM
			
			
			
		 |  
	| 
		
			
			| Developer |  | 
					Join Date: Dec 2007 
						Posts: 122
					      |  |  
	| 
				 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 |  
	
		
	
	
	
	
	| Thread Tools |  
	|  |  
	| Display Modes |  
	
	| 
		 Linear Mode |  
	| 
	|  Posting Rules |  
	| 
		
		You may not post new threads You may not post replies You may not post attachments You may not edit your posts 
 HTML code is Off 
 |  |  |  All times are GMT -4. The time now is 06:33 PM.
 
 |  |  
    |  |  |  |  
    |  |  |  |  
     |  |  |  |  
 |  |