Log in

View Full Version : Tradeskill Experience


Secrets
09-21-2010, 04:17 AM
This code allows tradeskills to have experience like a player would. Higher risk combines means higher experience gain.

It uses normal experience calculations up to an invisible level of 80, which would be 400 skill level. (400 / 5 = 80)

So far it's worked in my very limited testing. I only tested it up to level 19 from level 1.

It is hardcapped at level 400 for skill gains. Anything past 400 will not be calculated due to the issues with the current experience formula.

This does NOT make a character gain experience for it. This makes a character gain tradeskill experience stored in the extended profile. You can apply this experience stuff to all sorts of things by using AddSkillEXP, which was added to client to make this ultimately work. You could even apply it to combat skills, such as adding a perl function to add experience every time you give x items to an NPC. It's pretty limitless and only took 45 minutes to code/debug.

Hope you guys enjoy!


Index: common/extprofile.h
================================================== =================
--- common/extprofile.h (revision 1667)
+++ common/extprofile.h (working copy)
@@ -46,6 +46,7 @@

uint32 aa_effects;
uint32 perAA; //% of exp going to AAs
+ uint32 tradeskillxp[74];
};

#pragma pack()
Index: zone/client.h
================================================== =================
--- zone/client.h (revision 1667)
+++ zone/client.h (working copy)
@@ -438,8 +438,8 @@
bool Rampage();

inline uint32 GetEXP() const { return m_pp.exp; }
+ inline uint32 GetSkillEXP(uint16 skill) const { return m_epp.tradeskillxp[skill]; }

-
bool UpdateLDoNPoints(sint32 points, int32 theme);
void SetPVPPoints(uint32 Points) { m_pp.PVPCurrentPoints = Points; }
int32 GetPVPPoints() { return m_pp.PVPCurrentPoints; }
@@ -453,6 +453,8 @@

void AddEXP(uint32 in_add_exp, int8 conlevel = 0xFF, bool resexp = false);
void SetEXP(uint32 set_exp, uint32 set_aaxp, bool resexp=false);
+ void AddSkillEXP(uint32 in_add_exp, int8 conlevel = 0xFF, SkillType skill = _1H_BLUNT);
+ void SetSkillEXP(uint32 set_exp, SkillType arraypos = _1H_BLUNT);
void SetLeadershipEXP(uint32 group_exp, uint32 raid_exp);
void AddLeadershipEXP(uint32 group_exp, uint32 raid_exp);
void SendLeadershipEXPUpdate();
Index: zone/skillexp.cpp
================================================== =================
--- zone/skillexp.cpp (revision 0)
+++ zone/skillexp.cpp (revision 0)
@@ -0,0 +1,170 @@
+#ifdef SKILLEXP
+
+/* EQEMu: Everquest Server Emulator
+ Copyright (C) 2001-2003 EQEMu Development Team (http://eqemulator.net)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY except by those people which sell it, which
+ are required to give you total support for your newly bought product;
+ without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "../common/debug.h"
+#include "features.h"
+#include "masterentity.h"
+#include "StringIDs.h"
+#include "../common/MiscFunctions.h"
+#include "../common/rulesys.h"
+
+#ifdef EMBPERL
+#include "embparser.h"
+#endif
+
+
+
+void Client::AddSkillEXP(int32 in_add_exp, int8 conlevel, SkillType skill) {
+
+
+
+ /*
+ Few things to note here: It does use a con system like leveling does. It also shares exp formulas with leveling.
+ The only thing that is different is the display is done with a command instead of the HUD. (for now.)
+ */
+
+ int32 add_exp = in_add_exp;
+
+ if((XPRate != 0))
+ add_exp = static_cast<int32>(in_add_exp * (static_cast<float>(XPRate) / 100.0f));
+
+ float totalmod = 1.0;
+ float zemmod = 1.0;
+ //get modifiers
+ if(RuleR(Character, ExpMultiplier) >= 0){
+ totalmod *= RuleR(Character, ExpMultiplier);
+ }
+
+ /*
+
+ if(zone->newzone_data.zone_exp_multiplier >= 0){
+ zemmod *= zone->newzone_data.zone_exp_multiplier;
+ }
+
+ Enable if you want...
+ */
+
+ /*
+ if(RuleB(Character,UseRaceClassExpBonuses))
+ {
+ if(GetBaseRace() == HALFLING){
+ totalmod *= 1.05;
+ }
+
+ if(GetClass() == ROGUE || GetClass() == WARRIOR){
+ totalmod *= 1.05;
+ }
+ }
+ Enable this if you want... */
+
+ /*
+ if(zone->IsHotzone())
+ {
+ totalmod += RuleR(Zone, HotZoneBonus);
+ }
+ and this...*/
+ add_exp = int32(float(add_exp) * totalmod * zemmod);
+
+ if(RuleB(Character,UseXPConScaling))
+ {
+ if (conlevel != 0xFF) {
+ switch (conlevel)
+ {
+ case CON_GREEN:
+ add_exp = 0;
+ return;
+ case CON_LIGHTBLUE:
+ add_exp = add_exp * RuleI(Character, LightBlueModifier)/100;
+ break;
+ case CON_BLUE:
+ add_exp = add_exp * RuleI(Character, BlueModifier)/100;
+ break;
+ case CON_WHITE:
+ add_exp = add_exp * RuleI(Character, WhiteModifier)/100;
+ break;
+ case CON_YELLOW:
+ add_exp = add_exp * RuleI(Character, YellowModifier)/100;
+ break;
+ case CON_RED:
+ add_exp = add_exp * RuleI(Character, RedModifier)/100;
+ break;
+ }
+ }
+
+
+ }//end !resexp
+
+ float aatotalmod = 1.0;
+ if(zone->newzone_data.zone_exp_multiplier >= 0){
+ aatotalmod *= zone->newzone_data.zone_exp_multiplier;
+ }
+
+ if(RuleB(Character,UseRaceClassExpBonuses))
+ {
+ if(GetBaseRace() == HALFLING){
+ aatotalmod *= 1.05;
+ }
+
+ if(GetClass() == ROGUE || GetClass() == WARRIOR){
+ aatotalmod *= 1.05;
+ }
+ }
+
+ int32 exp = GetSkillEXP(skill) + add_exp;
+ SetSkillEXP(exp, skill);
+}
+
+void Client::SetSkillEXP(int32 set_exp, SkillType arraypos) {
+ _log(CLIENT__EXP, "Attempting to Set Trade Exp for %s (XP: %u)", this->GetCleanName(), set_exp);
+
+ if(set_exp == NULL)
+ return;
+
+
+ int16 check_level = (GetSkill(arraypos) / 5) + 1;
+
+ this->Message(15, "You gain skill experience! (Total XP Gained: %u / ToLevel %u)", set_exp, GetEXPForLevel(check_level + 1));
+
+ //check_level represents the level we should be when we have
+ //this ammount of exp (once these loops complete)
+ //see if we gained any levels
+ while (set_exp >= GetEXPForLevel(check_level)) {
+ check_level++;
+ }
+ check_level--;
+
+ /*
+ if ((GetLevel() != check_level) && !(check_level >= maxlevel))*/
+
+ if (((GetSkill(arraypos)) / 5) <= check_level && (GetSkill(arraypos)) != check_level){
+ SendLevelAppearance();
+ Message(15, "You have gained a skill level! Welcome to level %i!", GetSkill(arraypos) + 1);
+ SetSkill(arraypos, GetSkill(arraypos) + 1);
+ }
+
+ //If were at max level then stop gaining experience if we make it to the cap
+ if(GetSkill(arraypos) > 400){
+ SetSkill(arraypos, 400);
+ }
+
+ //set the client's EXP and AAEXP
+ m_epp.tradeskillxp[arraypos] = set_exp;
+}
+
+#endif
\ No newline at end of file
Index: zone/tradeskills.cpp
================================================== =================
--- zone/tradeskills.cpp (revision 1667)
+++ zone/tradeskills.cpp (working copy)
@@ -996,10 +996,29 @@

if (chance_stage2 > MakeRandomFloat(0, 99)) {
//Only if stage1 and stage2 succeeded you get a skillup.
+
+ #ifndef SKILLEXP
SetSkill(tradeskill, current_raw_skill + 1);
+ #else

- if(title_manager.IsNewTradeSkillTitleAvailable(tra deskill, current_raw_skill + 1))
+ if(chance_stage2 <= 5)
+ AddSkillEXP(EXP_FORMULA, CON_RED, tradeskill);
+ else if(chance_stage2 <= 25)
+ AddSkillEXP(EXP_FORMULA, CON_YELLOW, tradeskill);
+ else if(chance_stage2 <= 50)
+ AddSkillEXP(EXP_FORMULA, CON_WHITE, tradeskill);
+ else if(chance_stage2 <= 75)
+ AddSkillEXP(EXP_FORMULA, CON_BLUE, tradeskill);
+ else if(chance_stage2 <= 100)
+ AddSkillEXP(EXP_FORMULA, CON_LIGHTBLUE, tradeskill);
+ else
+ return;
+ #endif
+
+
+ if(title_manager.IsNewTradeSkillTitleAvailable(tra deskill, current_raw_skill + 1))
NotifyNewTitlesAvailable();
+ return;
}

_log(TRADESKILLS__TRACE, "...skillup_modifier: %f , success_modifier: %d , stat modifier: %d", skillup_modifier , success_modifier , stat_modifier);
Index: zone/Zone.vcproj
================================================== =================
--- zone/Zone.vcproj (revision 1667)
+++ zone/Zone.vcproj (working copy)
@@ -323,7 +323,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="C:\perl\lib\core"
- PreprocessorDefinitions="EMBPERL;EMBPERL_PLUGIN;SHAREMEM;i386;_WIN32_WINNT= 0x0400;ZONE;INVERSEXY;WIN32;_CONSOLE;FIELD_ITEMS;E QDEBUG=5;BOTS"
+ PreprocessorDefinitions="EMBPERL;EMBPERL_PLUGIN;SHAREMEM;i386;_WIN32_WINNT= 0x0400;ZONE;INVERSEXY;WIN32;_CONSOLE;FIELD_ITEMS;E QDEBUG=5;BOTS;SKILLEXP"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
PrecompiledHeaderFile=".\..\Build\ZonePerl/Zone.pch"
@@ -628,6 +628,10 @@
>
</File>
<File
+ RelativePath=".\skillexp.cpp"
+ >
+ </File>
+ <File
RelativePath=".\spawn2.cpp"
>
</File>

Secrets
09-21-2010, 04:19 AM
screenshot:

http://ilikekitti.es/tradeskillxp.png

lich2594
09-21-2010, 04:20 AM
Very nice work, Secrets. I can't wait to play around / experiment with it!