diff --git a/utils/sql/git/required/2013_04_07_Salvage.sql b/utils/sql/git/required/2013_04_07_Salvage.sql new file mode 100644 index 000000000..a98aad2f3 --- /dev/null +++ b/utils/sql/git/required/2013_04_07_Salvage.sql @@ -0,0 +1,11 @@ +-- Add row to tre +ALTER TABLE `tradeskill_recipe_entries` ADD `salvagecount` tinyint(2) DEFAULT '0' NOT NULL AFTER `componentcount`; + +-- Fix level req on Salvage +UPDATE `altadv_vars` SET `level_inc` = '5' WHERE `skill_id` = '997'; + +-- Set aa_effects for Salvage +INSERT INTO `aa_effects` (`id`, `aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('2374', '997', '1', '313', '5', '0'); +INSERT INTO `aa_effects` (`id`, `aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('2375', '998', '1', '313', '15', '0'); +INSERT INTO `aa_effects` (`id`, `aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('2376', '999', '1', '313', '25', '0'); + diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index d0c716cb0..cb2502c35 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -837,6 +837,9 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon) break; case SE_ForageAdditionalItems: newbon->ForageAdditionalItems += base1; + break; + case SE_Salvage: + newbon->SalvageChance += base1; break; case SE_ArcheryDamageModifier: newbon->ArcheryDamageModifier += base1; @@ -2197,6 +2200,10 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne case SE_ForageAdditionalItems: newbon->ForageAdditionalItems += effect_value; + break; + + case SE_Salvage: + newbon->SalvageChance += effect_value; break; case SE_ArcheryDamageModifier: @@ -3342,6 +3349,12 @@ void Mob::NegateSpellsBonuses(uint16 spell_id) spellbonuses.ForageAdditionalItems = effect_value; aabonuses.ForageAdditionalItems = effect_value; itembonuses.ForageAdditionalItems = effect_value; + break; + + case SE_Salvage: + spellbonuses.SalvageChance = effect_value; + aabonuses.SalvageChance = effect_value; + itembonuses.SalvageChance = effect_value; break; case SE_ArcheryDamageModifier: diff --git a/zone/common.h b/zone/common.h index df0853309..1d1aaffba 100644 --- a/zone/common.h +++ b/zone/common.h @@ -346,6 +346,7 @@ struct StatBonuses { uint8 FrontalBackstabChance; // Chance to backstab from the front for full damage uint8 ConsumeProjectile; // Chance to not consume arrow. uint8 ForageAdditionalItems; // Chance to forage another item. + uint8 SalvageChance; // Chance to salvage a tradeskill components on fail. uint16 ArcheryDamageModifier; // Increase Archery Damage by percent bool SecondaryDmgInc; // Allow off hand weapon to recieve damage bonus. uint16 GiveDoubleAttack; // Allow classes to double attack with a specified chance. diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index fa64de858..9b1973438 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -2716,6 +2716,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial) case SE_ArcheryDamageModifier: case SE_ConsumeProjectile: case SE_ForageAdditionalItems: + case SE_Salvage: case SE_FrontalBackstabChance: case SE_FrontalBackstabMinDmg: case SE_TripleBackstab: diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index 0f050368d..6c92fb158 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -1060,6 +1060,21 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) { SummonItem(itr->first, itr->second); itr++; } + + // Rolls on each item, is possible to return everything + int SalvageChance = aabonuses.SalvageChance + itembonuses.SalvageChance + spellbonuses.SalvageChance; + // Skip check if not a normal TS or if a quest recipe these should be nofail, but check amyways + if(SalvageChance && spec->tradeskill != 75 && !spec->quest) { + itr = spec->salvage.begin(); + uint8 sc = 0; + while(itr != spec->salvage.end()) { + for(sc = 0; sc < itr->second; sc++) + if(MakeRandomInt(0,99) < SalvageChance) + SummonItem(itr->first, 1); + itr++; + } + } + } return(false); } @@ -1404,8 +1419,45 @@ bool ZoneDatabase::GetTradeRecipe(uint32 recipe_id, uint8 c_type, uint32 some_id } mysql_free_result(result); } - safe_delete_array(query); - + + // Pull the salvage list + qlen = MakeAnyLenString(&query, "SELECT item_id,salvagecount FROM tradeskill_recipe_entries" + " WHERE salvagecount>0 AND recipe_id=%u", recipe_id); + + spec->salvage.clear(); + // Don't bother with the query if TS is nofail + if (!spec->nofail) { + if (RunQuery(query, qlen, errbuf, &result)) { + qcount = mysql_num_rows(result); + uint8 r; + for(r = 0; r < qcount; r++) { + row = mysql_fetch_row(result); + uint32 item = (uint32)atoi(row[0]); + uint8 num = (uint8)atoi(row[1]); + spec->salvage.push_back(pair(item, num)); + } + mysql_free_result(result); + } + + // Previous query returned nothing, default to component list + if (!spec->salvage.size()) { + qlen = MakeAnyLenString(&query, "SELECT item_id,componentcount FROM tradeskill_recipe_entries" + " WHERE componentcount>0 AND recipe_id=%u", recipe_id); + if (RunQuery(query, qlen, errbuf, &result)) { + qcount = mysql_num_rows(result); + uint8 r; + for(r =0; r < qcount; r++) { + row = mysql_fetch_row(result); + uint32 item = (uint32)atoi(row[0]); + uint8 num = (uint8)atoi(row[1]); + spec->salvage.push_back(pair(item, num)); + } + mysql_free_result(result); + } + } + } + safe_delete_array(query); + return(true); } diff --git a/zone/zonedb.h b/zone/zonedb.h index 545811525..d0f5dc9be 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -46,6 +46,7 @@ struct DBTradeskillRecipe_Struct { bool replace_container; vector< pair > onsuccess; vector< pair > onfail; + vector< pair > salvage; string name; uint8 must_learn; bool has_learnt;