These are fixes for a couple of bard issues I noticed. The first is that bards can gain instrument bonuses and skill levels for instruments that they aren't trained in. This code change prevents this until they meet the level requirements to get training at the bard GM.
Code:
Index: zone/client_mods.cpp
===================================================================
--- zone/client_mods.cpp (revision 403)
+++ zone/client_mods.cpp (working copy)
@@ -1465,6 +1465,8 @@
case PERCUSSION_INSTRUMENTS:
if(itembonuses.percussionMod == 0 && spellbonuses.percussionMod == 0)
effectmod = 10;
+ else if(GetSkill(PERCUSSION_INSTRUMENTS) == 0)
+ effectmod = 10;
else if(itembonuses.percussionMod > spellbonuses.percussionMod)
effectmod = itembonuses.percussionMod;
else
@@ -1473,6 +1475,8 @@
case STRINGED_INSTRUMENTS:
if(itembonuses.stringedMod == 0 && spellbonuses.stringedMod == 0)
effectmod = 10;
+ else if(GetSkill(STRINGED_INSTRUMENTS) == 0)
+ effectmod = 10;
else if(itembonuses.stringedMod > spellbonuses.stringedMod)
effectmod = itembonuses.stringedMod;
else
@@ -1481,6 +1485,8 @@
case WIND_INSTRUMENTS:
if(itembonuses.windMod == 0 && spellbonuses.windMod == 0)
effectmod = 10;
+ else if(GetSkill(WIND_INSTRUMENTS) == 0)
+ effectmod = 10;
else if(itembonuses.windMod > spellbonuses.windMod)
effectmod = itembonuses.windMod;
else
@@ -1489,6 +1495,8 @@
case BRASS_INSTRUMENTS:
if(itembonuses.brassMod == 0 && spellbonuses.brassMod == 0)
effectmod = 10;
+ else if(GetSkill(BRASS_INSTRUMENTS) == 0)
+ effectmod = 10;
else if(itembonuses.brassMod > spellbonuses.brassMod)
effectmod = itembonuses.brassMod;
else
Index: zone/spells.cpp
===================================================================
--- zone/spells.cpp (revision 403)
+++ zone/spells.cpp (working copy)
@@ -495,26 +495,42 @@
CheckIncreaseSkill(SINGING, -15);
break;
case PERCUSSION_INSTRUMENTS:
- if(this->itembonuses.percussionMod > 0)
- CheckIncreaseSkill(PERCUSSION_INSTRUMENTS, -15);
+ if(this->itembonuses.percussionMod > 0) {
+ if(GetRawSkill(PERCUSSION_INSTRUMENTS) > 0) // no skill increases if not trained in the instrument
+ CheckIncreaseSkill(PERCUSSION_INSTRUMENTS, -15);
+ else
+ Message_StringID(13,NO_INSTRUMENT_SKILL); // tell the client that they need instrument training
+ }
else
CheckIncreaseSkill(SINGING, -15);
break;
case STRINGED_INSTRUMENTS:
- if(this->itembonuses.stringedMod > 0)
- CheckIncreaseSkill(STRINGED_INSTRUMENTS, -15);
+ if(this->itembonuses.stringedMod > 0) {
+ if(GetRawSkill(STRINGED_INSTRUMENTS) > 0)
+ CheckIncreaseSkill(STRINGED_INSTRUMENTS, -15);
+ else
+ Message_StringID(13,NO_INSTRUMENT_SKILL);
+ }
else
CheckIncreaseSkill(SINGING, -15);
break;
case WIND_INSTRUMENTS:
- if(this->itembonuses.windMod > 0)
- CheckIncreaseSkill(WIND_INSTRUMENTS, -15);
+ if(this->itembonuses.windMod > 0) {
+ if(GetRawSkill(WIND_INSTRUMENTS) > 0)
+ CheckIncreaseSkill(WIND_INSTRUMENTS, -15);
+ else
+ Message_StringID(13,NO_INSTRUMENT_SKILL);
+ }
else
CheckIncreaseSkill(SINGING, -15);
break;
case BRASS_INSTRUMENTS:
- if(this->itembonuses.brassMod > 0)
- CheckIncreaseSkill(BRASS_INSTRUMENTS, -15);
+ if(this->itembonuses.brassMod > 0) {
+ if(GetRawSkill(BRASS_INSTRUMENTS) > 0)
+ CheckIncreaseSkill(BRASS_INSTRUMENTS, -15);
+ else
+ Message_StringID(13,NO_INSTRUMENT_SKILL);
+ }
else
CheckIncreaseSkill(SINGING, -15);
break;
Index: zone/StringIDs.h
===================================================================
--- zone/StringIDs.h (revision 403)
+++ zone/StringIDs.h (working copy)
@@ -191,4 +191,5 @@
#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
+#define NO_INSTRUMENT_SKILL 269 // "Stick to singing until you learn to play this instrument."
#endif
The other change I made is to implement the Song of Sustenance. This makes it unnecessary for the bard's group to eat or drink while the song is in effect. The client stops auto-consuming on its own, but the server still decreases the character's stamina. To fix it without having to scan through a character's buffs every time a stamina update goes out, I just made the buff itself add food/drink every tic.
The buff tics get called 7 times for every one stamina update, so I needed to bump the stamina decrease from 32 to 35 to make it a multiple of 7 (the food consumption rate seems ridiculously slow to me anyway). Alternatively, it can be left at 32 and the characters will just get a slow increase in food/drink level while the song is in effect.
Code:
Index: zone/client_process.cpp
===================================================================
--- zone/client_process.cpp (revision 403)
+++ zone/client_process.cpp (working copy)
@@ -1679,9 +1679,9 @@
if(zone->GetZoneID() != 151) {
if (m_pp.hunger_level > 0)
- m_pp.hunger_level-=32;
+ m_pp.hunger_level-=35;
if (m_pp.thirst_level > 0)
- m_pp.thirst_level-=32;
+ m_pp.thirst_level-=35;
sta->food = m_pp.hunger_level;
sta->water = m_pp.thirst_level;
}
Index: zone/spell_effects.cpp
===================================================================
--- zone/spell_effects.cpp (revision 403)
+++ zone/spell_effects.cpp (working copy)
@@ -1905,9 +1905,9 @@
#ifdef SPELL_EFFECT_SPAM
snprintf(effect_desc, _EDLEN, "Hunger");
#endif
- // solar: TODO implement this
- const char *msg = "Hunger is not implemented.";
- if(caster) caster->Message(13, msg);
+ // auto-eating is taken care of client side
+ // stamina is handled by DoBuffTic()
+
break;
}
@@ -2965,6 +2965,16 @@
break;
}
+ case SE_Hunger: {
+ // this procedure gets called 7 times for every once that the stamina update occurs so we add 1/7 of the subtraction.
+ // It's far from perfect, but works without any unnecessary buff checks to bog down the server.
+ if(IsClient()) {
+ CastToClient()->m_pp.hunger_level += 5;
+ CastToClient()->m_pp.thirst_level += 5;
+ }
+ break;
+ }
+
/* case SE_Charm: { //Do it once in Effect instead of every tic
bool bBreak = false;