Leere
11-25-2010, 03:33 AM
This should fix two problems. The first was reported over on PEQTGC (link (http://www.peqtgc.com/phpBB2/viewtopic.php?t=11486)). Basically items were consumed as their existence was checked, even if the spell would then fail due to missing some of the later listed ones. I've separated the check and the consumption. Also, all the missing items are now listed, not just the first one encountered.
The second problem was the reagent conservation focus check. It was possible for it to trigger for SE_SummonItem effects and the likes. (Focus check returned 0, the random was 0-100 and a <= check.)
Moving the check for the for-loop continue is probably pointless penny-pinching with memory lookups, I know, but since I was already modifying the code near them...
Index: spells.cpp
================================================== =================
--- spells.cpp (revision 1744)
+++ spells.cpp (working copy)
@@ -921,20 +921,21 @@
// first check for component reduction
if(IsClient()) {
int reg_focus = CastToClient()->GetFocusEffect(focusReagentCost,spell_id);
- if(MakeRandomInt(0, 100) <= reg_focus) {
+ // reg_focus of 0 has to fail for SE_SummonItem spells
+ if(MakeRandomInt(1, 100) <= reg_focus) {
mlog(SPELLS__CASTING, "Spell %d: Reagent focus item prevented reagent consumption (%d chance)", spell_id, reg_focus);
} else {
if(reg_focus > 0)
mlog(SPELLS__CASTING, "Spell %d: Reagent focus item failed to prevent reagent consumption (%d chance)", spell_id, reg_focus);
Client *c = this->CastToClient();
- int component, component_count, inv_slot_id;
- for(int t_count = 0; t_count < 4; t_count++) {
+ int component, component_count, inv_slot_id, t_count;
+ bool missingreags = false;
+ for(t_count = 0; t_count < 4; t_count++) {
component = spells[spell_id].components[t_count];
+ if (component == -1)
+ continue;
component_count = spells[spell_id].component_counts[t_count];
- if (component == -1)
- continue;
-
// bard components are requirements for a certain instrument type, not a specific item
if(bard_song_mode) {
bool HasInstrument = true;
@@ -996,7 +997,10 @@
else {
if(c->GetInv().HasItem(component, component_count, invWhereWorn|invWherePersonal) == -1) // item not found
{
- c->Message_StringID(13, MISSING_SPELL_COMP);
+ if (!missingreags) {
+ c->Message_StringID(13, MISSING_SPELL_COMP);
+ missingreags = true;
+ }
const Item_Struct *item = database.GetItem(component);
if(item) {
@@ -1008,35 +1012,41 @@
strcpy((char*)&TempItemName, "UNKNOWN");
mlog(SPELLS__CASTING_ERR, "Spell %d: Canceled. Missing required reagent %s (%d)", spell_id, TempItemName, component);
}
+ }
+ } // end bard/not bard ifs
+ } // end reagent check loop
+ if (missingreags) {
+ 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 {
+ for(t_count = 0; t_count < 4; t_count++) {
+ component = spells[spell_id].components[t_count];
+ if (component == -1)
+ continue;
+ component_count = spells[spell_id].component_counts[t_count];
- 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++)
{
- 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++)
+ inv_slot_id = c->GetInv().HasItem(component, 1, invWhereWorn|invWherePersonal);
+ if(inv_slot_id != -1)
{
- 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?");
- }
+ 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?");
+ }
}
- } // end bard/not bard ifs
- } // end reagent loop
+ } // end reagent consumption loop
+ } // end missingreags if
} // end `focus did not help us`
} // end IsClient() for reagents
The second problem was the reagent conservation focus check. It was possible for it to trigger for SE_SummonItem effects and the likes. (Focus check returned 0, the random was 0-100 and a <= check.)
Moving the check for the for-loop continue is probably pointless penny-pinching with memory lookups, I know, but since I was already modifying the code near them...
Index: spells.cpp
================================================== =================
--- spells.cpp (revision 1744)
+++ spells.cpp (working copy)
@@ -921,20 +921,21 @@
// first check for component reduction
if(IsClient()) {
int reg_focus = CastToClient()->GetFocusEffect(focusReagentCost,spell_id);
- if(MakeRandomInt(0, 100) <= reg_focus) {
+ // reg_focus of 0 has to fail for SE_SummonItem spells
+ if(MakeRandomInt(1, 100) <= reg_focus) {
mlog(SPELLS__CASTING, "Spell %d: Reagent focus item prevented reagent consumption (%d chance)", spell_id, reg_focus);
} else {
if(reg_focus > 0)
mlog(SPELLS__CASTING, "Spell %d: Reagent focus item failed to prevent reagent consumption (%d chance)", spell_id, reg_focus);
Client *c = this->CastToClient();
- int component, component_count, inv_slot_id;
- for(int t_count = 0; t_count < 4; t_count++) {
+ int component, component_count, inv_slot_id, t_count;
+ bool missingreags = false;
+ for(t_count = 0; t_count < 4; t_count++) {
component = spells[spell_id].components[t_count];
+ if (component == -1)
+ continue;
component_count = spells[spell_id].component_counts[t_count];
- if (component == -1)
- continue;
-
// bard components are requirements for a certain instrument type, not a specific item
if(bard_song_mode) {
bool HasInstrument = true;
@@ -996,7 +997,10 @@
else {
if(c->GetInv().HasItem(component, component_count, invWhereWorn|invWherePersonal) == -1) // item not found
{
- c->Message_StringID(13, MISSING_SPELL_COMP);
+ if (!missingreags) {
+ c->Message_StringID(13, MISSING_SPELL_COMP);
+ missingreags = true;
+ }
const Item_Struct *item = database.GetItem(component);
if(item) {
@@ -1008,35 +1012,41 @@
strcpy((char*)&TempItemName, "UNKNOWN");
mlog(SPELLS__CASTING_ERR, "Spell %d: Canceled. Missing required reagent %s (%d)", spell_id, TempItemName, component);
}
+ }
+ } // end bard/not bard ifs
+ } // end reagent check loop
+ if (missingreags) {
+ 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 {
+ for(t_count = 0; t_count < 4; t_count++) {
+ component = spells[spell_id].components[t_count];
+ if (component == -1)
+ continue;
+ component_count = spells[spell_id].component_counts[t_count];
- 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++)
{
- 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++)
+ inv_slot_id = c->GetInv().HasItem(component, 1, invWhereWorn|invWherePersonal);
+ if(inv_slot_id != -1)
{
- 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?");
- }
+ 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?");
+ }
}
- } // end bard/not bard ifs
- } // end reagent loop
+ } // end reagent consumption loop
+ } // end missingreags if
} // end `focus did not help us`
} // end IsClient() for reagents