eq4me |
09-10-2006 12:46 AM |
Ok, some bugs fixed and implemented the skillup formula. Unless there are bugs creeping up I consider it done for now. Maybe I will get back to it later and implement the Tradeskill AAs. Depends if this makes it into the EQEmu source. ;)
The ups
For determining skillups now the higher of INT or WIS(and in some cases STR or DEX too) will be used instead of just INT.
If you succeed on an item the chance for an skillup is higher.
You have now a good chance to succeed on an item with an trivial more than 30 above your skill.
Once an item has reached trivial the chance to succeed is 95% plus 1% per 40 skillpoints above trivial.
The downs
Chance to succeed is no longer modified by any stat. (Not really an issue since the success rates with a skill well under trivial are so much better)
Skillups might be slower on high skill levels.
Some tradeskills are harder to raise than others.
Look for my comments how to tweak the success and skillup rates to your liking.
Below is a diff to tradeskills.cpp and client.h from EQEmu Version 7.0.0-845
Code:
--- zone/tradeskills.cpp-orig 2006-09-07 19:04:51.927543012 +0000
+++ zone/tradeskills.cpp 2006-09-10 12:26:01.738867547 +0000
@@ -652,6 +652,41 @@
float chance = 0;
+ float skillup_modifier;
+ sint16 thirdstat = 0;
+ sint16 stat_modifier = 15;
+ uint16 success_modifier;
+
+ // Rework based on the info on eqtraders.com
+ // http://mboards.eqtraders.com/eq/showthread.php?t=22246
+ // 09/10/2006 v0.1 (eq4me)
+ // 09/11/2006 v0.2 (eq4me)
+ // Todo:
+ // Implementing AAs
+ // Success modifiers based on recipes
+ // Skillup modifiers based on the rarity of the ingredients
+
+ // Some tradeskills are more eqal then others. ;-)
+ // If you want to customize the stage1 success rate do it here.
+ // Remember: skillup_modifier is (float). Lower is better.
+ if (tradeskill == ALCHEMY || tradeskill == FLETCHING || tradeskill == JEWELRY_MAKING || tradeskill == POTTERY) {
+ skillup_modifier = 4;
+ } else if (tradeskill == BAKING || tradeskill == BREWING) {
+ skillup_modifier = 3;
+ } else if (tradeskill == RESEARCH) {
+ skillup_modifier = 1;
+ } else
+ skillup_modifier = 2;
+
+ // Some tradeskills take the higher of one additional stat beside INT and WIS
+ // to determine the skillup rate. Additionally these tradeskills do not have an
+ // -15 modifier on their statbonus.
+ if (tradeskill == FLETCHING || tradeskill == MAKE_POISON) {
+ thirdstat = GetDEX();
+ stat_modifier = 0;
+ } else if (tradeskill == BLACKSMITHING) {
+ thirdstat = GetSTR();
+ stat_modifier = 0;
+ }
- // statbonus 20%/10% with 200 + 0.05% / 0.025% per point above 200
- float wisebonus = (m_pp.WIS > 200) ? 20 + ((m_pp.WIS - 200) * 0.05) : m_pp.WIS * 0.1;
- float intbonus = (m_pp.INT > 200) ? 10 + ((m_pp.INT - 200) * 0.025) : m_pp.INT * 0.05;
+ sint16 higher_from_int_wis = (GetINT() > GetWIS()) ? GetINT() : GetWIS();
+ sint16 bonusstat = (higher_from_int_wis > thirdstat) ? higher_from_int_wis : thirdstat;
@@ -662,23 +697,37 @@
chance = 100; //cannot fail.
+ #ifdef TRADESKILL_SPAM
+ Message(0, "...This combine cannot fail.");
+ #endif
} else if(((sint16)user_skill - (sint16)spec->skill_needed) < 0) {
- chance = 0;
- //impossible... is there a message for this???
- } else if (((sint16)user_skill - (sint16)spec->trivial) >= 0) {
- chance = 80+wisebonus-10; // 80% basechance + max 20% stats
+ // Minimum chance is always 5
+ chance = 5;
+ } else if(((sint16)user_skill - (sint16)spec->trivial) == 0) {
+ // At reaching trivial the chance goes to 95% going up an additional
+ // percent for every 40 skillpoints above the trivial.
+ // The success rate is not modified through stats.
+ // Mastery AAs are unaccounted for so far.
+ // chance_AA = chance + ((100 - chance) * mastery_modifier)
+ // But the 95% limit with an additional 1% for every 40 skill points
+ // above critical still stands.
+ // Mastery modifier is: 10%/25%/50% for rank one/two/three
+ chance = 95;
+ Message_StringID(4,TRADESKILL_TRIVIAL);
+ } else if (((sint16)user_skill - (sint16)spec->trivial) > 0) {
+ chance = (sint16)((user_skill - spec->trivial) / 40) + 95;
+ if (chance > 100) {
+ chance = 100;
+ }
Message_StringID(4,TRADESKILL_TRIVIAL);
} else {
- if ((spec->trivial - user_skill) < 20) {
- // 40 base chance success + max 40% skill + 20% max stats
- chance = 40 + wisebonus + 40 - ((spec->trivial - user_skill)*2);
+ // For trivials over 68 the chance is (skill - 0.75*trivial) +51.5
+ // For trivial up to 68 the chance is (skill - trivial) + 66
+ if (spec->trivial >= 68) {
+ chance = (user_skill - (0.75*spec->trivial)) + 51.5;
}
else {
- // 0 base chance success + max 30% skill + 10% max stats
- chance = 0 + (wisebonus/2) + 30 - (((spec->trivial - user_skill) * (spec->trivial - user_skill))*0.01875);
+ chance = (user_skill - spec->trivial) + 66;
}
-
-//Is there a reason we dont use CheckIncreaseSkill()?
- // skillincrease?
- if ((55-(user_skill*0.236))+intbonus > (float)rand()/RAND_MAX*100) {
- SetSkill(tradeskill, GetRawSkill(tradeskill) + 1);
- //Message(4, "You have become better at (skillid=%i)", tradeskill);
+ //Just because I am paranoid
+ if (chance >95) {
+ chance = 95;
}
@@ -688,4 +738,11 @@
if ((tradeskill==75) || GetGM() || (chance > res)){
+ success_modifier = 1;
+ CheckIncreaseTradeskill(bonusstat, stat_modifier, skillup_modifier, success_modifier, tradeskill);
Message_StringID(4,TRADESKILL_SUCCEED);
+ #ifdef TRADESKILL_SPAM
+ Message(0, "...Current skill: %d , Trivial: %d , Success chance: %f percent", user_skill , spec->trivial , chance);
+ Message(0, "...Bonusstat: %d , INT: %d , WIS: %d , DEX: %d , STR: %d", bonusstat , GetINT() , GetWIS() , GetDEX() , GetSTR());
+ #endif
+
itr = spec->onsuccess.begin();
@@ -698,4 +755,11 @@
} else {
+ success_modifier = 2; // Halves the chance
+ CheckIncreaseTradeskill(bonusstat, stat_modifier, skillup_modifier, success_modifier, tradeskill);
Message_StringID(4,TRADESKILL_FAILED);
+ #ifdef TRADESKILL_SPAM
+ Message(0, "...Current skill: %d , Trivial: %d , Success chance: %f percent", user_skill , spec->trivial , chance);
+ Message(0, "...Bonusstat: %d , INT: %d , WIS: %d , DEX: %d , STR: %d", bonusstat , GetINT() , GetWIS() , GetDEX() , GetSTR());
+ #endif
+
itr = spec->onfail.begin();
@@ -711,2 +776,40 @@
+void Client::CheckIncreaseTradeskill(sint16 bonusstat, sint16 stat_modifier, float skillup_modifier, uint16 success_modifier, uint16 tradeskill)
+{
+ uint16 current_raw_skill = GetRawSkill(tradeskill);
+ float chance_stage2 = 0;
+
+ //A successfull combine doubles the stage1 chance for an skillup
+ //Some tradeskill are harder than others. See above for more.
+ float chance_stage1 = (bonusstat - stat_modifier) / (skillup_modifier * success_modifier);
+
+ //In stage2 the only thing that matters is your current unmodified skill.
+ //If you want to customize here you probbably need to implement your own
+ //formula instead of tweaking the below one.
+ if (chance_stage1 > (float)rand()/RAND_MAX*100) {
+ if (current_raw_skill < 15) {
+ // Allways succeed
+ chance_stage2 = 100;
+ } else if (current_raw_skill < 175) {
+ //From skill 16 to 174 your chance of success falls linearly from 92% to 13%.
+ chance_stage2 = (200 - current_raw_skill) / 2;
+ } else {
+ //At skill 175, your chance of success falls linearly from 12.5% to 2.5% at skill 300.
+ chance_stage2 = 12.5 - (.08 * (current_raw_skill - 175));
+ }
+ }
+
+ if (chance_stage2 > (float)rand()/RAND_MAX*100) {
+ //Only if stage1 and stage2 succeeded you get a skillup.
+ SetSkill(tradeskill, current_raw_skill + 1);
+ }
+
+ #ifdef TRADESKILL_SPAM
+ Message(0, "...skillup_modifier: %f , success_modifier: %d , stat modifier: %d", skillup_modifier , success_modifier , stat_modifier);
+ Message(0, "...Stage1 chance was: %f percent", chance_stage1);
+ Message(0, "...Stage2 chance was: %f percent. 0 percent means stage1 failed", chance_stage2);
+ #endif
+ return;
+}
+
--- zone/client.h-orig 2006-09-10 12:39:04.311101098 +0000
+++ zone/client.h 2006-09-10 10:48:51.852853481 +0000
@@ -491,2 +491,4 @@
bool TradeskillExecute(DBTradeskillRecipe_Struct *spec, uint16 tradeskill);
+ //eq4me additions
+ void CheckIncreaseTradeskill(sint16, sint16, float, uint16, uint16);
|